--- /dev/null
+library ieee;
+
+use ieee.std_logic_1164.all;
+
+USE ieee.std_logic_signed.ALL;
+
+USE ieee.std_logic_arith.ALL;
+
+USE std.textio.ALL;
+USE ieee.std_logic_textio.ALL;
+
+entity trb_net_sbuf_testbench is
+
+end trb_net_sbuf_testbench;
+
+architecture trb_net_sbuf_testbench_arch of trb_net_sbuf_testbench is
+
+ signal clk : std_logic := '0';
+ signal reset : std_logic := '1';
+
+ signal dr_in,syn_rd : std_logic := '0';
+
+component trb_net_sbuf is
+
+ generic (DATA_WIDTH : integer := 56;
+ VERSION: integer := 1);
+-- generic (DATA_WIDTH : integer := 1);
+
+ port(
+ -- Misc
+ CLK : in std_logic;
+ RESET : in std_logic;
+ CLK_EN : in std_logic;
+ -- port to combinatorial logic
+ COMB_DATAREADY_IN: in STD_LOGIC; --comb logic provides data word
+ COMB_next_READ_OUT: out STD_LOGIC; --sbuf can read in NEXT cycle
+ COMB_READ_IN: in STD_LOGIC; --comb logic IS reading
+ -- the COMB_next_READ_OUT should be connected via comb. logic to a register
+ -- to provide COMB_READ_IN (feedback path with 1 cycle delay)
+ -- The "REAL" READ_OUT can be constructed in the comb via COMB_next_READ_
+ -- OUT and the READ_IN: If one of these is ='1', no problem to read in next
+ -- step.
+ COMB_DATA_IN: in STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word
+ -- Port to synchronous output.
+ SYN_DATAREADY_OUT: out STD_LOGIC;
+ SYN_DATA_OUT: out STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word
+ SYN_READ_IN: in STD_LOGIC;
+ -- Status and control port
+ STAT_BUFFER: out STD_LOGIC
+ );
+END component;
+
+begin
+
+UUT: trb_net_sbuf
+ generic map (DATA_WIDTH => 1,
+ VERSION => 0)
+ port map (
+ CLK => clk,
+ RESET => reset,
+ CLK_EN => '1',
+
+ COMB_DATAREADY_IN => dr_in,
+ COMB_READ_IN=> '1',
+ COMB_DATA_IN => (others => '0'),
+ SYN_READ_IN => syn_rd
+ );
+
+
+ clk <= not clk after 10ns;
+
+
+ DO_RESET : process
+ begin
+ reset <= '1';
+ wait for 30ns;
+ reset <= '0';
+ wait;
+ end process DO_RESET;
+
+ STIMULI: process (clk)
+ file protokoll : text open read_mode is "in_sbuf.txt";
+ variable myoutline : line;
+ variable leer : character;
+ variable var1, var2 : std_logic;
+
+ begin
+ if falling_edge(CLK) then
+ if (not endfile(protokoll)) then
+ readline(protokoll,myoutline);
+
+ read(myoutline,var1);
+ dr_in <= var1;
+ read(myoutline,leer);
+
+ read(myoutline,var2);
+ syn_rd <= var2;
+
+
+ end if;
+ end if;
+ end process STIMULI;
+
+end trb_net_sbuf_testbench_arch;
+
+
+-- fuse -prj trb_net_sbuf_testbench_beh.prj -top trb_net_sbuf_testbench -o trb_net_sbuf_testbench
+
+-- trb_net_sbuf_testbench -tclbatch sbuf_testsim.tcl
+-- gtkwave vcdfile.vcd settings_sbuf.sav
type BUFFER_STATE is (BUFFER_EMPTY, BUFFER_B2_FULL, BUFFER_B1_FULL);
signal current_buffer_state, next_buffer_state : BUFFER_STATE;
+ signal current_buffer_state_int : STD_LOGIC_VECTOR (1 downto 0);
signal current_got_overflow, next_got_overflow : std_logic;
signal combined_COMB_DATAREADY_IN: std_logic;
signal use_current_b1_buffer: std_logic;
- begin
-
- COMB_next_READ_OUT <= current_next_READ_OUT;
+begin
+ SYN_DATA_OUT <= current_b2_buffer;
+ SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT;
+ STAT_BUFFER <= current_got_overflow;
- SYN_DATA_OUT <= current_b2_buffer;
- SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT;
+ combined_COMB_DATAREADY_IN <= (COMB_DATAREADY_IN and COMB_READ_IN);
- STAT_BUFFER <= current_got_overflow;
+ GEN1: if VERSION = 0 generate
+ MUX: process (use_current_b1_buffer,
+ COMB_DATA_IN, current_b1_buffer)
+ begin -- simple MUX
+ if use_current_b1_buffer = '1' then
+ next_b2_buffer <= current_b1_buffer;
+ else
+ next_b2_buffer <= COMB_DATA_IN;
+ end if;
+ end process;
+ end generate;
+
+ GEN2: if VERSION = 1 generate
+ next_b2_buffer <= COMB_DATA_IN;
+ end generate;
- combined_COMB_DATAREADY_IN <= (COMB_DATAREADY_IN and COMB_READ_IN);
+ COMB: process (current_buffer_state, COMB_DATAREADY_IN, COMB_READ_IN,
+ SYN_READ_IN, COMB_DATA_IN, current_b1_buffer, current_b2_buffer,
+ current_SYN_DATAREADY_OUT, current_got_overflow,
+ combined_COMB_DATAREADY_IN, current_next_READ_OUT)
+ begin -- process COMB
+ next_buffer_state <= current_buffer_state;
+ next_next_READ_OUT <= '1';
+ if VERSION = 0 then
+ next_b1_buffer <= COMB_DATA_IN;
+ move_b1_buffer <= '0';
+ end if;
+ use_current_b1_buffer <= '0'; --by default COMB_DATA_IN;
+ move_b2_buffer <= '0';
+
+ next_SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT;
+ next_got_overflow <= current_got_overflow;
- GEN1: if VERSION = 0 generate
- MUX: process (use_current_b1_buffer,
- COMB_DATA_IN, current_b1_buffer)
- begin -- simple MUX
- if use_current_b1_buffer = '1' then
- next_b2_buffer <= current_b1_buffer;
- else
- next_b2_buffer <= COMB_DATA_IN;
+ if current_buffer_state = BUFFER_EMPTY then
+ current_buffer_state_int <= "00";
+ if combined_COMB_DATAREADY_IN = '1' then
+ -- COMB logic is writing into the sbuf
+ next_buffer_state <= BUFFER_B2_FULL;
+ if VERSION = 1 then
+ next_next_READ_OUT <= '0';
end if;
- end process;
- end generate;
-
- GEN2: if VERSION = 1 generate
- next_b2_buffer <= COMB_DATA_IN;
- end generate;
-
-COMB: process (current_buffer_state, COMB_DATAREADY_IN, COMB_READ_IN,
- SYN_READ_IN, COMB_DATA_IN, current_b1_buffer, current_b2_buffer,
- current_SYN_DATAREADY_OUT, current_got_overflow,
- combined_COMB_DATAREADY_IN, current_next_READ_OUT)
-begin -- process COMB
- next_buffer_state <= current_buffer_state;
- next_next_READ_OUT <= '1';
- if VERSION = 0 then
- next_b1_buffer <= COMB_DATA_IN;
- move_b1_buffer <= '0';
- end if;
- use_current_b1_buffer <= '0'; --by default COMB_DATA_IN;
- move_b2_buffer <= '0';
-
- next_SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT;
- next_got_overflow <= current_got_overflow;
-
- if current_buffer_state = BUFFER_EMPTY then
- if combined_COMB_DATAREADY_IN = '1' then
- -- COMB logic is writing into the sbuf
- next_buffer_state <= BUFFER_B2_FULL;
- if VERSION = 1 then
+ move_b2_buffer <= '1';
+ next_SYN_DATAREADY_OUT <= '1';
+ end if;
+ elsif current_buffer_state = BUFFER_B2_FULL then
+ current_buffer_state_int <= "01";
+ if combined_COMB_DATAREADY_IN = '1' and SYN_READ_IN = '1' then
+ -- COMB logic is writing into the sbuf
+ -- at the same time syn port is reading
+ next_buffer_state <= BUFFER_B2_FULL;
+ if VERSION = 1 then
+ next_next_READ_OUT <= '0';
+ end if;
+ move_b2_buffer <= '1';
+ next_SYN_DATAREADY_OUT <= '1';
+ elsif combined_COMB_DATAREADY_IN = '1' then
+ -- ONLY COMB logic is writing into the sbuf
+ -- this is the case when we should use the additional
+ -- buffer
+ next_buffer_state <= BUFFER_B1_FULL;
+ next_next_READ_OUT <= '0'; --PLEASE stop writing
+ move_b1_buffer <= '1';
+ next_SYN_DATAREADY_OUT <= '1';
+ elsif SYN_READ_IN = '1' then
+ next_buffer_state <= BUFFER_EMPTY;
+ next_SYN_DATAREADY_OUT <= '0';
+ else
+ next_buffer_state <= BUFFER_B2_FULL;
next_next_READ_OUT <= '0';
+ next_SYN_DATAREADY_OUT <= '1';
end if;
- move_b2_buffer <= '1';
- next_SYN_DATAREADY_OUT <= '1';
+ elsif current_buffer_state = BUFFER_B1_FULL then
+ current_buffer_state_int <= "10";
+ if combined_COMB_DATAREADY_IN = '1' and SYN_READ_IN = '1' then
+ -- COMB logic is writing into the sbuf
+ -- at the same time syn port is reading
+ next_buffer_state <= BUFFER_B1_FULL;
+ next_next_READ_OUT <= '0';
+ use_current_b1_buffer <= '1';
+ move_b1_buffer <= '1';
+ move_b2_buffer <= '1';
+ next_SYN_DATAREADY_OUT <= '1';
+ elsif combined_COMB_DATAREADY_IN = '1' then
+ -- ONLY COMB logic is writing into the sbuf
+ -- FATAL ERROR
+ next_got_overflow <= '1';
+ next_buffer_state <= BUFFER_B1_FULL;
+ next_next_READ_OUT <= '0'; --PLEASE stop writing
+ next_SYN_DATAREADY_OUT <= '1';
+ elsif SYN_READ_IN = '1' then
+ next_buffer_state <= BUFFER_B2_FULL;
+ use_current_b1_buffer <= '1';
+ move_b1_buffer <= '1';
+ move_b2_buffer <= '1';
+ next_next_READ_OUT <= '0';
+ next_SYN_DATAREADY_OUT <= '1';
+ else
+ next_buffer_state <= BUFFER_B1_FULL;
+ next_next_READ_OUT <= '0';
+ next_SYN_DATAREADY_OUT <= '1';
+ end if;
end if;
- elsif current_buffer_state = BUFFER_B2_FULL then
- if combined_COMB_DATAREADY_IN = '1' and SYN_READ_IN = '1' then
- -- COMB logic is writing into the sbuf
- -- at the same time syn port is reading
- next_buffer_state <= BUFFER_B2_FULL;
- if VERSION = 1 then
+ -- for version1 it is more complicated: we have to gate
+ -- the signal: when somebody is writing, we have to stop
+ -- all the activity. I do this in the following way: If I
+ -- promised to take the data, I stop the data taking in the
+ -- following cycle. This reduces the bandwidth by a factor of
+ -- 2
+
+ if VERSION = 1 then
+ if current_next_READ_OUT = '1' then
next_next_READ_OUT <= '0';
end if;
- move_b2_buffer <= '1';
- next_SYN_DATAREADY_OUT <= '1';
- elsif combined_COMB_DATAREADY_IN = '1' then
- -- ONLY COMB logic is writing into the sbuf
- -- this is the case when we should use the additional
- -- buffer
- next_buffer_state <= BUFFER_B1_FULL;
- next_next_READ_OUT <= '0'; --PLEASE stop writing
- move_b1_buffer <= '1';
- next_SYN_DATAREADY_OUT <= '1';
- elsif SYN_READ_IN = '1' then
- next_buffer_state <= BUFFER_EMPTY;
- next_SYN_DATAREADY_OUT <= '0';
- else
- next_buffer_state <= BUFFER_B2_FULL;
- next_next_READ_OUT <= '0';
- next_SYN_DATAREADY_OUT <= '1';
end if;
- elsif current_buffer_state = BUFFER_B1_FULL then
-
- if combined_COMB_DATAREADY_IN = '1' and SYN_READ_IN = '1' then
- -- COMB logic is writing into the sbuf
- -- at the same time syn port is reading
- next_buffer_state <= BUFFER_B1_FULL;
- next_next_READ_OUT <= '0';
- use_current_b1_buffer <= '1';
- move_b1_buffer <= '1';
- move_b2_buffer <= '1';
- next_SYN_DATAREADY_OUT <= '1';
- elsif combined_COMB_DATAREADY_IN = '1' then
- -- ONLY COMB logic is writing into the sbuf
- -- FATAL ERROR
- next_got_overflow <= '1';
- next_buffer_state <= BUFFER_B1_FULL;
- next_next_READ_OUT <= '0'; --PLEASE stop writing
- next_SYN_DATAREADY_OUT <= '1';
- elsif SYN_READ_IN = '1' then
- next_buffer_state <= BUFFER_B2_FULL;
- use_current_b1_buffer <= '1';
- move_b1_buffer <= '1';
- move_b2_buffer <= '1';
- next_next_READ_OUT <= '0';
- next_SYN_DATAREADY_OUT <= '1';
- else
- next_buffer_state <= BUFFER_B1_FULL;
- next_next_READ_OUT <= '0';
- next_SYN_DATAREADY_OUT <= '1';
- end if;
- end if;
-
- -- for version1 it is more complicated: we have to gate
- -- the signal: when somebody is writing, we have to stop
- -- all the activity. I do this in the following way: If I
- -- promised to take the data, I stop the data taking in the
- -- following cycle. This reduces the bandwidth by a factor of
- -- 2
-
- if VERSION = 1 then
- if current_next_READ_OUT = '1' then
- next_next_READ_OUT <= '0';
+
+ end process COMB;
+
+-- the next lines are an emergency stop
+-- unfortuanally unregistered
+-- this is needed because the final READ_OUT has
+-- to be known 2 clk cycles in advance, which is
+-- almost impossible taking into account that
+-- the SYN reader may release the RD signal at any point
+-- if this is the case, BREAK
+
+ EM_STOP : process(current_next_READ_OUT, SYN_READ_IN, current_SYN_DATAREADY_OUT,
+ current_buffer_state)
+ begin
+ COMB_next_READ_OUT <= current_next_READ_OUT;
+ if VERSION = 0 then
+ if SYN_READ_IN = '0' and current_SYN_DATAREADY_OUT = '1'
+ and current_buffer_state = BUFFER_B2_FULL then
+ COMB_next_READ_OUT <= '0';
+ end if;
end if;
- end if;
-
-end process COMB;
+ end process EM_STOP;
-
- REG : process(CLK)
- begin
+ REG : process(CLK)
+ begin
if rising_edge(CLK) then
if RESET = '1' then
current_buffer_state <= BUFFER_EMPTY;
current_next_READ_OUT <= current_next_READ_OUT;
end if;
end if;
- end process;
+ end process;
- GEN6: if VERSION = 0 generate
+ GEN6: if VERSION = 0 generate
REG2 : process(CLK)
begin
- if rising_edge(CLK) then
- if RESET = '1' then
- current_b1_buffer <= (others => '0');
- elsif move_b1_buffer = '1' then
- current_b1_buffer <= next_b1_buffer;
- else
- current_b1_buffer <= current_b1_buffer;
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ current_b1_buffer <= (others => '0');
+ elsif move_b1_buffer = '1' then
+ current_b1_buffer <= next_b1_buffer;
+ else
+ current_b1_buffer <= current_b1_buffer;
+ end if;
end if;
- end if;
end process;
- end generate;
+ end generate;
- REG3 : process(CLK)
- begin
+ REG3 : process(CLK)
+ begin
if rising_edge(CLK) then
if RESET = '1' then
current_b2_buffer <= (others => '0');
current_b2_buffer <= current_b2_buffer;
end if;
end if;
- end process;
+ end process;
end trb_net_sbuf_arch;
-
+