From 6edf38df670e50bf185e19938c198de5e0aff8dc Mon Sep 17 00:00:00 2001 From: hadaq Date: Wed, 15 Aug 2007 11:34:17 +0000 Subject: [PATCH] removed logic bug in sbuf, Ingo --- testbench/in_sbuf.txt | 14 ++ testbench/sbuf_testsim.tcl | 4 + testbench/settings_sbuf.sav | 11 + testbench/trb_net_sbuf_testbench.vhd | 110 +++++++++ testbench/trb_net_sbuf_testbench_beh.prj | 3 + trb_net_sbuf.vhd | 281 ++++++++++++----------- 6 files changed, 291 insertions(+), 132 deletions(-) create mode 100644 testbench/in_sbuf.txt create mode 100644 testbench/sbuf_testsim.tcl create mode 100644 testbench/settings_sbuf.sav create mode 100644 testbench/trb_net_sbuf_testbench.vhd create mode 100644 testbench/trb_net_sbuf_testbench_beh.prj diff --git a/testbench/in_sbuf.txt b/testbench/in_sbuf.txt new file mode 100644 index 0000000..9b85872 --- /dev/null +++ b/testbench/in_sbuf.txt @@ -0,0 +1,14 @@ +0:0 +0:0 +0:0 +0:0 +1:0 +1:0 +1:0 +0:1 +0:1 +0:1 +0:1 +0:1 +0:1 +0:0 diff --git a/testbench/sbuf_testsim.tcl b/testbench/sbuf_testsim.tcl new file mode 100644 index 0000000..f9eb6ef --- /dev/null +++ b/testbench/sbuf_testsim.tcl @@ -0,0 +1,4 @@ +vcd dumpfile vcdfile.vcd +vcd dumpvars -m /UUT/ +run 1000 ns +quit \ No newline at end of file diff --git a/testbench/settings_sbuf.sav b/testbench/settings_sbuf.sav new file mode 100644 index 0000000..b9ca433 --- /dev/null +++ b/testbench/settings_sbuf.sav @@ -0,0 +1,11 @@ +[size] 1272 936 +[pos] -1 -1 +*-27.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +@28 +trb_net_sbuf_testbench.UUT.comb_dataready_in +trb_net_sbuf_testbench.UUT.clk +trb_net_sbuf_testbench.UUT.comb_next_read_out +trb_net_sbuf_testbench.UUT.syn_read_in +trb_net_sbuf_testbench.UUT.syn_dataready_out +#current_buffer_state_int[1:0] trb_net_sbuf_testbench.UUT.current_buffer_state_int[1] trb_net_sbuf_testbench.UUT.current_buffer_state_int[0] +trb_net_sbuf_testbench.UUT.current_got_overflow diff --git a/testbench/trb_net_sbuf_testbench.vhd b/testbench/trb_net_sbuf_testbench.vhd new file mode 100644 index 0000000..f2c9578 --- /dev/null +++ b/testbench/trb_net_sbuf_testbench.vhd @@ -0,0 +1,110 @@ +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 diff --git a/testbench/trb_net_sbuf_testbench_beh.prj b/testbench/trb_net_sbuf_testbench_beh.prj new file mode 100644 index 0000000..0b24b4a --- /dev/null +++ b/testbench/trb_net_sbuf_testbench_beh.prj @@ -0,0 +1,3 @@ +vhdl work "../trb_net_std.vhd" +vhdl work "../trb_net_sbuf.vhd" +vhdl work "trb_net_sbuf_testbench.vhd" diff --git a/trb_net_sbuf.vhd b/trb_net_sbuf.vhd index 8639b16..88c61dc 100644 --- a/trb_net_sbuf.vhd +++ b/trb_net_sbuf.vhd @@ -60,144 +60,161 @@ architecture trb_net_sbuf_arch of trb_net_sbuf is 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; @@ -216,26 +233,26 @@ end process COMB; 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'); @@ -245,10 +262,10 @@ end process COMB; current_b2_buffer <= current_b2_buffer; end if; end if; - end process; + end process; end trb_net_sbuf_arch; - + -- 2.43.0