spriteflyer_top_rtl.vhd 8.81 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--------------------------------------------------------------------------------
-- Fault InJection Instrumenter (FIJI)
-- https://embsys.technikum-wien.at/projects/vecs/fiji
--
-- Copyright (C) 2017 Christian Fibich <fibich@technikum-wien.at>
-- Copyright (C) 2017 Stefan Tauner <tauner@technikum-wien.at>
--
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 0.51 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-0.51. Unless required by applicable
-- law or agreed to in writing, software, hardware and materials
-- distributed under this License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or
-- implied. See the License for the specific language governing
-- permissions and limitations under the License.
--
-- See the LICENSE file for more details.
--
-- Description:
--  TMR_VGA top-level entity file
--------------------------------------------------------------------------------


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

library work;
    use work.spriteflyer_pkg.all;

entity spriteflyer_top is
    generic (
        G_CLK_FREQUENCY : natural := 50000000;  -- Clock frequency in Hz
        G_RED_WIDTH     : natural := 4;         -- Width of the red DAC
        G_GREEN_WIDTH   : natural := 4;         -- Width of the green DAC
        G_BLUE_WIDTH    : natural := 4;         -- Width of the blue DAC
        G_HSYNC_ACT     : std_logic := '0';     -- Active level of HSYNC (some boards might use inverting buffers)
        G_VSYNC_ACT     : std_logic := '0';     -- Active level of HSYNC (some boards might use inverting buffers)
        G_LED_ON        : std_logic := '0'      -- Active (lit) level of the connected LEDs (on some boards the FPGA is used as source)
    );
    port (
        s_clk_i      : in std_logic;            -- System clock
        s_reset_x_i  : in std_logic;            -- Reset signal
        s_tmr_en_i   : in std_logic;            -- TMR enable switch
        s_red_o      : out std_logic_vector(G_RED_WIDTH-1 downto 0);    -- VGA red bus to DAC
        s_green_o    : out std_logic_vector(G_GREEN_WIDTH-1 downto 0);  -- VGA green bus to DAC
        s_blue_o     : out std_logic_vector(G_BLUE_WIDTH-1 downto 0);   -- VGA blue bus to DAC
        s_hsync_o    : out std_logic;           -- VGA HSYNC
        s_vsync_o    : out std_logic;           -- VGA VSYNC
        s_ledg_o     : out std_logic_vector(3 downto 0)  -- status LEDs
    );
end entity spriteflyer_top;

architecture rtl of spriteflyer_top is

    -- VGA raster counters
    signal s_line_count   : unsigned(9 downto 0); -- 0 to 799
    signal s_column_count : unsigned(9 downto 0); -- 0 to 524

    -- Clock, reset, 25Mhz clock enable
    signal s_clk, s_reset_n, s_ce25 : std_logic;

    -- blank: inhibit output, image finished strobe
    signal s_blank, s_image_finished : std_logic;

    signal s_red_tmr_partitions   : std_logic_vector(3*G_RED_WIDTH-1 downto 0);
    signal s_green_tmr_partitions : std_logic_vector(3*G_GREEN_WIDTH-1 downto 0);
    signal s_blue_tmr_partitions  : std_logic_vector(3*G_BLUE_WIDTH-1 downto 0);
    signal s_tmr_en               : std_logic;

    -- Error outputs from voters
    signal s_red_err, s_green_err, s_blue_err             : std_logic;

    -- LED output registers (LEDs stay on if 
    signal s_red_err_led, s_green_err_led, s_blue_err_led : std_logic;

    attribute syn_keep : boolean;

    -- Need to set this attribute, otherwise Synplify merges the voters
    attribute syn_keep of s_red_tmr_partitions   : signal is true;
    attribute syn_keep of s_green_tmr_partitions : signal is true;
    attribute syn_keep of s_blue_tmr_partitions  : signal is true;

    -- Need to set this attribute, otherwise Synplify removes the signals
    attribute syn_keep of s_red_err   : signal is true;
    attribute syn_keep of s_green_err : signal is true;
    attribute syn_keep of s_blue_err  : signal is true;

begin

    -- switch the each LED on (Level specified by G_LED_ON)
    -- when the corresponding value is '1'
    s_ledg_o <= (s_red_err_led & s_green_err_led & s_blue_err_led & (s_red_err_led or s_green_err_led or s_blue_err_led)) xnor (G_LED_ON & G_LED_ON & G_LED_ON & G_LED_ON);

    -- Clock Generator: Provide clock and low-active reset signal
    i_spriteflyer_clkgen : spriteflyer_clkgen
        port map (
            s_clk_i     => s_clk_i,
            s_reset_x_i => s_reset_x_i,
            s_clk_o     => s_clk,
            s_ce25_o    => s_ce25,
            s_reset_n_o => s_reset_n
        );

    -- Synchronize and debounce the TMR enable button
    i_tmr_enable_sync_debounce : spriteflyer_input_sync_debounce
        generic map (
            G_CLK_FREQUENCY => G_CLK_FREQUENCY
        )
        port map (
            s_clk_i      => s_clk,
            s_reset_n_i  => s_reset_n,
            s_data_i     => s_tmr_en_i,
            s_data_deb_o => s_tmr_en
        );

    -- Instantiate the VGA timing generator
    i_vga_timing : spriteflyer_vga
        generic map (
        G_HSYNC_ACT   => G_HSYNC_ACT,
        G_VSYNC_ACT   => G_VSYNC_ACT
        )
        port map (
            s_clk_i         => s_clk,
            s_reset_n_i        => s_reset_n,
            s_ce25_i           => s_ce25,
            s_column_count_o   => s_column_count,
            s_line_count_o     => s_line_count,
            s_blank_o          => s_blank,
            s_image_finished_o => s_image_finished,
            s_hsync_o          => s_hsync_o,
            s_vsync_o          => s_vsync_o
        );

    -- Triplicate the pixel generator logic
    generate_tmr_partitions : for i in 0 to 2 generate
        attribute syn_noprune : boolean;
        attribute syn_noprune of i_sprite : label is true;
    begin
        i_sprite : spriteflyer_sprite
            generic map (
            G_RED_WIDTH   => G_RED_WIDTH,
            G_GREEN_WIDTH => G_GREEN_WIDTH,
            G_BLUE_WIDTH  => G_BLUE_WIDTH
            )
            port map (
                s_clk_i         => s_clk,
                s_reset_n_i        => s_reset_n,
                s_ce25_i           => s_ce25,
                s_column_count_i   => s_column_count,
                s_line_count_i     => s_line_count,
                s_blank_i          => s_blank,
                s_image_finished_i => s_image_finished,
                s_red_o            => s_red_tmr_partitions(G_RED_WIDTH*(i+1)-1 downto G_RED_WIDTH*i),
                s_green_o          => s_green_tmr_partitions(G_GREEN_WIDTH*(i+1)-1 downto G_GREEN_WIDTH*i),
                s_blue_o           => s_blue_tmr_partitions(G_BLUE_WIDTH*(i+1)-1 downto G_BLUE_WIDTH*i)
            );
    end generate;

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    -- Instantiate the voters
    --
    -- Note: Voting is only performed over the RGB outputs of the three
    -- spriteflyer (Sprite Engine) instances. This masks errors in one
    -- of the three instances which propagate to the outputs. It does
    -- NOT correct the internal state of the instances. Thus, errors
    -- affecting the internal state (e.g., the position of the sprite)
    -- lead to a permanent difference between the instance where the
    -- error ocurred to the other two. For better resilience against soft
    -- errors, voting should also be performed over the state registers,
    -- as described e.g., in [1].
    --
    -- [1] N. Battezzati, L. Sterpone, and M. Violante, Reconfigurable
    --     field programmable gate arrays for mission-critical
    --     applications. Springer, 2011. 

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    i_voter_red : spriteflyer_voter 
        generic map (
            G_WIDTH => G_RED_WIDTH
        )
        port map (
            s_en_i   => s_tmr_en,
            s_data_i => s_red_tmr_partitions,
            s_data_o => s_red_o,
            s_err_o  => s_red_err
        );

    i_voter_green : spriteflyer_voter 
        generic map (
            G_WIDTH => G_GREEN_WIDTH
        )
        port map (
            s_en_i   => s_tmr_en,
            s_data_i => s_green_tmr_partitions,
            s_data_o => s_green_o,
            s_err_o  => s_green_err
        );

    i_voter_blue : spriteflyer_voter 
        generic map (
            G_WIDTH => G_BLUE_WIDTH
        )
        port map (
            s_en_i   => s_tmr_en,
            s_data_i => s_blue_tmr_partitions,
            s_data_o => s_blue_o,
            s_err_o  => s_blue_err
        );

    p_error_leds : process (s_clk, s_reset_n)
    begin
        if s_reset_n = '0' then
            s_red_err_led   <= '0';
            s_green_err_led <= '0';
            s_blue_err_led  <= '0';
        elsif s_clk'event and s_clk = '1' then
            s_red_err_led   <= s_red_err_led   or s_red_err;
            s_green_err_led <= s_green_err_led or s_green_err;
            s_blue_err_led  <= s_blue_err_led  or s_blue_err;
        end if;
    end process p_error_leds;

end rtl;