From 38754466738365129960209d8d08bca9de9b9656 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Wed, 14 Feb 2007 12:32:20 +0000 Subject: [PATCH] demux part of multiplexer done, Ingo --- testbench/in_io_multiplexer.txt | 17 ++ testbench/io_multiplexer_settings.sav | 12 ++ testbench/io_multiplexer_testsim.tcl | 5 + .../trb_net_io_multiplexer_testbench.vhd | 143 ++++++++++++++++ .../trb_net_io_multiplexer_testbench_beh.prj | 7 + trb_net_io_multiplexer.vhd | 150 ++++++++++------- trb_net_pattern_gen.vhd | 8 +- trb_net_priority_arbiter.vhd | 2 +- trb_net_sbuf.vhd | 159 ++++++++++++++++++ 9 files changed, 437 insertions(+), 66 deletions(-) create mode 100644 testbench/in_io_multiplexer.txt create mode 100644 testbench/io_multiplexer_settings.sav create mode 100644 testbench/io_multiplexer_testsim.tcl create mode 100644 testbench/trb_net_io_multiplexer_testbench.vhd create mode 100644 testbench/trb_net_io_multiplexer_testbench_beh.prj create mode 100644 trb_net_sbuf.vhd diff --git a/testbench/in_io_multiplexer.txt b/testbench/in_io_multiplexer.txt new file mode 100644 index 0000000..f634b7a --- /dev/null +++ b/testbench/in_io_multiplexer.txt @@ -0,0 +1,17 @@ +0000:0 +0000:0 +0000:0 +1011:1 +0000:1 +0000:1 +0101:1 +0010:1 +0011:1 +1111:1 +1111:1 +1111:1 +1111:1 +1111:1 +1111:1 +1111:1 +0000:1 diff --git a/testbench/io_multiplexer_settings.sav b/testbench/io_multiplexer_settings.sav new file mode 100644 index 0000000..a020895 --- /dev/null +++ b/testbench/io_multiplexer_settings.sav @@ -0,0 +1,12 @@ +[size] 1272 936 +[pos] -1 -1 +*-26.000000 90000000 -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_io_multiplexer_testbench.UUT.clk +trb_net_io_multiplexer_testbench.UUT.med_dataready_in +#med_data_in[3:0] trb_net_io_multiplexer_testbench.UUT.med_data_in[3] trb_net_io_multiplexer_testbench.UUT.med_data_in[2] trb_net_io_multiplexer_testbench.UUT.med_data_in[1] trb_net_io_multiplexer_testbench.UUT.med_data_in[0] +trb_net_io_multiplexer_testbench.UUT.med_read_out +#int_dataready_out[3:0] trb_net_io_multiplexer_testbench.UUT.int_dataready_out[3] trb_net_io_multiplexer_testbench.UUT.int_dataready_out[2] trb_net_io_multiplexer_testbench.UUT.int_dataready_out[1] trb_net_io_multiplexer_testbench.UUT.int_dataready_out[0] +#int_data_out[7:0] trb_net_io_multiplexer_testbench.UUT.int_data_out[7] trb_net_io_multiplexer_testbench.UUT.int_data_out[6] trb_net_io_multiplexer_testbench.UUT.int_data_out[5] trb_net_io_multiplexer_testbench.UUT.int_data_out[4] trb_net_io_multiplexer_testbench.UUT.int_data_out[3] trb_net_io_multiplexer_testbench.UUT.int_data_out[2] trb_net_io_multiplexer_testbench.UUT.int_data_out[1] trb_net_io_multiplexer_testbench.UUT.int_data_out[0] +@22 +#int_read_in[3:0] trb_net_io_multiplexer_testbench.UUT.int_read_in[3] trb_net_io_multiplexer_testbench.UUT.int_read_in[2] trb_net_io_multiplexer_testbench.UUT.int_read_in[1] trb_net_io_multiplexer_testbench.UUT.int_read_in[0] diff --git a/testbench/io_multiplexer_testsim.tcl b/testbench/io_multiplexer_testsim.tcl new file mode 100644 index 0000000..d607c67 --- /dev/null +++ b/testbench/io_multiplexer_testsim.tcl @@ -0,0 +1,5 @@ +vcd dumpfile vcdfile.vcd +vcd dumpvars -m /UUT/ +vcd dumpvars -m /UUT/DEFDR/ +run 1000 ns +quit \ No newline at end of file diff --git a/testbench/trb_net_io_multiplexer_testbench.vhd b/testbench/trb_net_io_multiplexer_testbench.vhd new file mode 100644 index 0000000..d1d6d3e --- /dev/null +++ b/testbench/trb_net_io_multiplexer_testbench.vhd @@ -0,0 +1,143 @@ +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_io_multiplexer_testbench is + +end trb_net_io_multiplexer_testbench; + +architecture trb_net_io_multiplexer_testbench_arch of trb_net_io_multiplexer_testbench is + + signal clk : std_logic := '0'; + signal reset : std_logic := '1'; + + signal read_type : std_logic_vector(2 downto 0) := (others => '0'); + signal read_f2 : std_logic_vector(3 downto 0) := (others => '0'); + signal read_f1 : std_logic_vector(7 downto 0) := (others => '0'); + signal rol_mask : std_logic := '0'; + signal ctrl: std_logic_vector(31 downto 0) := (others => '0'); + + component trb_net_io_multiplexer is + + generic (BUS_WIDTH : integer := 56; + MULT_WIDTH : integer := 5); + + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + -- Media direction port + MED_DATAREADY_IN: in STD_LOGIC; + MED_DATA_IN: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest + -- bits are + -- mult. + MED_READ_OUT: out STD_LOGIC; + + MED_DATAREADY_OUT: out STD_LOGIC; + MED_DATA_OUT: out STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest + -- bits are + -- mult. + MED_READ_IN: in STD_LOGIC; + + -- Internal direction port + INT_DATAREADY_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); + INT_DATA_OUT: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0); + INT_READ_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); + + INT_DATAREADY_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0); + INT_DATA_IN: in STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0); + INT_READ_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); + + + + -- Status and control port + STAT: out STD_LOGIC_VECTOR (31 downto 0) + ); + + end component; + + signal med_dataready_in : std_logic := '0'; + signal med_data_in: STD_LOGIC_VECTOR(3 downto 0) := "0000"; + +begin + + UUT: trb_net_io_multiplexer + generic map ( + BUS_WIDTH => 4, + MULT_WIDTH => 2 + ) + port map ( + CLK =>clk, + RESET => reset, + CLK_EN => '1', + + MED_DATAREADY_IN => med_dataready_in, + MED_DATA_IN => med_data_in, + + MED_READ_IN => '1', + + -- Internal direction port + -- INT_READ_IN => (others => '0'), + INT_READ_IN => (others => '1'), + + INT_DATAREADY_IN => (others => '0'), + INT_DATA_IN => (others => '0') + + ); + + clk <= not clk after 10ns; +-- ctrl(9) <= rol_mask; + + DO_RESET : process + begin + reset <= '1'; + wait for 30ns; + reset <= '0'; +-- ctrl(8 downto 0) <= "100000000"; --only fixed +-- ctrl(8 downto 0) <= "111111111"; --only rr +-- ctrl(8 downto 0) <= "101010101"; --mixed + wait for 20ns; +-- ctrl(8 downto 0) <= "000000000"; + wait; + end process DO_RESET; + + STIMULI: process (clk) + file protokoll : text open read_mode is "in_io_multiplexer.txt"; + variable myoutline : line; + variable leer : character; + variable var1, var2 : std_logic; + variable varx1 : std_logic_vector(2 downto 0); + variable varx2, varx3 : std_logic_vector(3 downto 0); + begin + if falling_edge(CLK) then + if (not endfile(protokoll)) then + readline(protokoll,myoutline); + + read(myoutline,varx2); + med_data_in <= varx2; + read(myoutline,leer); + + read(myoutline,var1); + med_dataready_in <= var1; + + end if; + end if; + end process STIMULI; + + +end trb_net_io_multiplexer_testbench_arch; + +-- fuse -prj trb_net_io_multiplexer_testbench_beh.prj -top trb_net_io_multiplexer_testbench -o trb_net_io_multiplexer_testbench + +-- trb_net_io_multiplexer_testbench -tclbatch io_multiplexer_testsim.tcl + +-- + diff --git a/testbench/trb_net_io_multiplexer_testbench_beh.prj b/testbench/trb_net_io_multiplexer_testbench_beh.prj new file mode 100644 index 0000000..7626f8d --- /dev/null +++ b/testbench/trb_net_io_multiplexer_testbench_beh.prj @@ -0,0 +1,7 @@ +vhdl work "../trb_net_std.vhd" +vhdl work "../trb_net_priority_encoder.vhd" +vhdl work "../trb_net_priority_arbiter.vhd" +vhdl work "../trb_net_pattern_gen.vhd" +vhdl work "../trb_net_sbuf.vhd" +vhdl work "../trb_net_io_multiplexer.vhd" +vhdl work "trb_net_io_multiplexer_testbench.vhd" diff --git a/trb_net_io_multiplexer.vhd b/trb_net_io_multiplexer.vhd index d696579..6558b72 100644 --- a/trb_net_io_multiplexer.vhd +++ b/trb_net_io_multiplexer.vhd @@ -11,8 +11,8 @@ use work.trb_net_std.all; entity trb_net_io_multiplexer is - generic (BUS_WIDTH : integer := 51; - MULT_WIDTH : integer := 1); + generic (BUS_WIDTH : integer := 56; + MULT_WIDTH : integer := 5); port( -- Misc @@ -21,25 +21,22 @@ entity trb_net_io_multiplexer is CLK_EN : in std_logic; -- Media direction port MED_DATAREADY_IN: in STD_LOGIC; - MED_DATA_IN: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest - -- bits are - -- mult. - MED_READ_OUT: out STD_LOGIC; - - MED_DATAREADY_OUT: in STD_LOGIC; - MED_DATA_OUT: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest - -- bits are - -- mult. - MED_READ_IN: out STD_LOGIC; + MED_DATA_IN: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); + -- highest bits are mult. + MED_READ_OUT: out STD_LOGIC; + + MED_DATAREADY_OUT: out STD_LOGIC; + MED_DATA_OUT: out STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); + MED_READ_IN: in STD_LOGIC; -- Internal direction port INT_DATAREADY_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); INT_DATA_OUT: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0); INT_READ_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); - INT_DATAREADY_IN: out STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0); - INT_DATA_IN: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0); - INT_READ_OUT: in STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); + INT_DATAREADY_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0); + INT_DATA_IN: in STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0); + INT_READ_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0); @@ -59,13 +56,42 @@ architecture trb_net_io_multiplexer_arch of trb_net_io_multiplexer is RESULT_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0) ); END component; + + component trb_net_sbuf is + + generic (DATA_WIDTH : integer := 56); + + 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_VECTOR (31 downto 0); + CTRL_BUFFER: in STD_LOGIC_VECTOR (31 downto 0) + ); + END component; - signal current_demux_buffer, next_demux_buffer: STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); - signal current_demux_empty, next_demux_empty: STD_LOGIC; - signal current_demux_READ, next_demux_READ: STD_LOGIC; - signal current_demux_dr, next_demux_dr: STD_LOGIC_VECTOR ((2**MULT_WIDTH)-1 downto 0); + signal demux_next_READ, current_demux_READ : STD_LOGIC_VECTOR ((2**MULT_WIDTH)-1 downto 0); + signal next_demux_dr, next_demux_dr_tmp: STD_LOGIC_VECTOR ((2**MULT_WIDTH)-1 downto 0); signal demux_read: STD_LOGIC; -- buffer is read out and killed + signal current_MED_READ_OUT, next_MED_READ_OUT: STD_LOGIC; + signal current_mux_buffer, next_mux_buffer: STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); signal current_mux_empty, next_mux_empty: STD_LOGIC; signal current_mux_DR, next_mux_DR: STD_LOGIC; @@ -80,71 +106,73 @@ architecture trb_net_io_multiplexer_arch of trb_net_io_multiplexer is ------------------------------------------------------------------------------ -- the simpler part is the demux - demux_read <= (current_demux_dr and INT_READ_IN); + G1: for i in 0 to 2**MULT_WIDTH-1 generate + G2: trb_net_sbuf + generic map (DATA_WIDTH => BUS_WIDTH-MULT_WIDTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + COMB_DATAREADY_IN => next_demux_dr(i), + COMB_next_READ_OUT => demux_next_READ(i), + COMB_READ_IN => current_demux_READ(i), + COMB_DATA_IN => MED_DATA_IN (BUS_WIDTH-MULT_WIDTH-1 downto 0), + SYN_DATAREADY_OUT => INT_DATAREADY_OUT(i), + SYN_DATA_OUT => INT_DATA_OUT ((BUS_WIDTH-MULT_WIDTH)*(i+1)-1 downto (BUS_WIDTH-MULT_WIDTH)*(i)), + SYN_READ_IN => INT_READ_IN(i), +-- STAT_BUFFER => + CTRL_BUFFER => (others => '0') + ); + end generate; + + MED_READ_OUT <= current_MED_READ_OUT; - comb_demux : process (current_demux_empty, demux_read, current_demux_buffer, - current_demux_READ, MED_DATAREADY_IN, current_demux_dr, - INT_READ_IN) + comb_demux : process (next_demux_dr_tmp, demux_next_READ, INT_READ_IN, + MED_DATAREADY_IN, current_MED_READ_OUT) begin -- process - next_demux_READ <= '0'; - next_demux_buffer <= current_demux_buffer; - demux_read <='1'; - next_demux_empty <= current_demux_empty; - if (current_demux_dr and INT_READ_IN) = (others => '0') then - demux_read <= '0'; -- no read from int point + next_demux_dr <= (others => '0'); + current_demux_READ <= (others => '0'); + -- generate the READ_OUT + next_MED_READ_OUT <= or_all(demux_next_READ or INT_READ_IN); + -- (follow instruction on sbuf) + + current_demux_READ <= (others => '0'); + if current_MED_READ_OUT = '1' then + current_demux_READ <= (others => '1'); end if; - if current_demux_empty = '1' or demux_read = '1' then --- no problem to read in next step - next_demux_READ <= '1'; + if current_MED_READ_OUT = '1' and MED_DATAREADY_IN = '1' then + next_demux_dr <= next_demux_dr_tmp; --enable DR on the sbufs end if; - if current_demux_READ = '1' and MED_DATAREADY_IN = '1' then ---definition of read - next_demux_buffer <= MED_DATA_IN; - next_demux_empty <= '0'; - elsif demux_read = '1' then -- only read from int - next_demux_empty <= '1'; - end if; end process; -- define next DRx - DEF_DR: trb_net_pattern_gen + DEFDR: trb_net_pattern_gen generic map (MULT_WIDTH => MULT_WIDTH) port map ( - INPUT_IN => next_demux_buffer (BUS_WIDTH-1 downto (BUS_WIDTH-MULT_WIDTH)), - RESULT_OUT => next_demux_dr + INPUT_IN => MED_DATA_IN(BUS_WIDTH-1 downto (BUS_WIDTH-MULT_WIDTH)), + RESULT_OUT => next_demux_dr_tmp -- this will have a 1 in ANY case ); sync_demux : process(CLK) begin if rising_edge(CLK) then if RESET = '1' then - current_demux_buffer <= (others => '0'); - current_demux_empty <= '0'; - current_demux_READ <= '0'; - current_demux_dr <= (others => '0'); + current_MED_READ_OUT <= '0'; elsif CLK_EN = '1' then - current_demux_buffer <= next_demux_buffer; - current_demux_empty <= next_demux_empty; - current_demux_READ <= next_demux_READ; - current_demux_dr <= next_demux_dr; + current_MED_READ_OUT <= next_MED_READ_OUT; else - current_demux_buffer <= current_demux_buffer; - current_demux_empty <= current_demux_empty; - current_demux_READ <= current_demux_READ; - current_demux_dr <= current_demux_dr; + current_MED_READ_OUT <= current_MED_READ_OUT; end if; end if; end process; - INT_DATAREADY_OUT <= current_demux_dr; - -- logic is much simpler when hardwire the fan-out - -- this might cause problems with timing, lets see - G1: for i in 2**MULT_WIDTH-1 downto 0 generate + +-- G3: for i in 2**MULT_WIDTH-1 downto 0 generate - INT_DATA_OUT((BUS_WIDTH-MULT_WIDTH)*(2**(i+1))-1 downto (BUS_WIDTH-MULT_WIDTH)*(2**i)) - <= current_demux_buffer ; - end generate; +-- INT_DATA_OUT((BUS_WIDTH-MULT_WIDTH)*((i+1))-1 downto (BUS_WIDTH-MULT_WIDTH)*(i)) +-- <= current_demux_buffer(BUS_WIDTH-MULT_WIDTH-1 downto 0) ; +-- end generate; end trb_net_io_multiplexer_arch; diff --git a/trb_net_pattern_gen.vhd b/trb_net_pattern_gen.vhd index aaa4cae..6d70ee3 100644 --- a/trb_net_pattern_gen.vhd +++ b/trb_net_pattern_gen.vhd @@ -15,18 +15,18 @@ entity trb_net_pattern_gen is generic (MULT_WIDTH : integer := 3); port( - INPUT_IN : in STD_LOGIC_VECTOR (MULT_WIDTH downto 0); - RESULT_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0) + INPUT_IN : in STD_LOGIC_VECTOR (MULT_WIDTH-1 downto 0); + RESULT_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0) ); END trb_net_pattern_gen; architecture trb_net_pattern_gen_arch of trb_net_pattern_gen is begin - G1: for i in 2**MULT_WIDTH downto 0 generate + G1: for i in 0 to 2**MULT_WIDTH-1 generate G2: process (INPUT_IN) begin -- process - if (2**i) = INPUT_IN then + if i = INPUT_IN then RESULT_OUT(i) <= '1'; else RESULT_OUT(i) <= '0'; diff --git a/trb_net_priority_arbiter.vhd b/trb_net_priority_arbiter.vhd index cbfbeb2..6a0fb0a 100755 --- a/trb_net_priority_arbiter.vhd +++ b/trb_net_priority_arbiter.vhd @@ -7,7 +7,7 @@ use work.trb_net_std.all; entity trb_net_priority_arbiter is - generic (WIDTH : integer := 32); + generic (WIDTH : integer := 16); port( -- Misc diff --git a/trb_net_sbuf.vhd b/trb_net_sbuf.vhd new file mode 100644 index 0000000..e009b99 --- /dev/null +++ b/trb_net_sbuf.vhd @@ -0,0 +1,159 @@ +------------------------------------------------------------------------------- +-- Single buffer with one more buffer to keep the speed of the datalink +-- The sbuf can be connected to a combinatorial logic (as an output buffer) +-- to provide the synchronous logic +------------------------------------------------------------------------------- + + + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_ARITH.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +use work.trb_net_std.all; + +entity trb_net_sbuf is + + generic (DATA_WIDTH : integer := 56); + + 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_VECTOR (31 downto 0); + CTRL_BUFFER: in STD_LOGIC_VECTOR (31 downto 0) + ); +END trb_net_sbuf; + +architecture trb_net_sbuf_arch of trb_net_sbuf is + + signal current_b1_buffer, next_b1_buffer : STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); + signal current_b2_buffer, next_b2_buffer : STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); + signal next_next_READ_OUT, current_next_READ_OUT : std_logic; + signal next_SYN_DATAREADY_OUT, current_SYN_DATAREADY_OUT : std_logic; + + type BUFFER_STATE is (BUFFER_EMPTY, BUFFER_B2_FULL, BUFFER_B1_FULL); + signal current_buffer_state, next_buffer_state : BUFFER_STATE; + + signal current_got_overflow, next_got_overflow : std_logic; + + begin + + COMB_next_READ_OUT <= current_next_READ_OUT; + SYN_DATA_OUT <= current_b2_buffer; + SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT; + + STAT_BUFFER(0) <= current_got_overflow; + STAT_BUFFER(31 downto 1) <= (others => '0'); + +COMB: process (current_buffer_state, COMB_DATAREADY_IN, COMB_READ_IN, + SYN_READ_IN, COMB_DATA_IN, current_b1_buffer, current_b2_buffer) +begin -- process COMB + next_buffer_state <= current_buffer_state; + next_next_READ_OUT <= '1'; + next_b2_buffer <= current_b2_buffer; + next_b1_buffer <= current_b1_buffer; + next_SYN_DATAREADY_OUT <= '0'; + next_got_overflow <= current_got_overflow; + if current_buffer_state = BUFFER_EMPTY then + if COMB_DATAREADY_IN = '1' and COMB_READ_IN = '1' then + -- COMB logic is writing into the sbuf + next_buffer_state <= BUFFER_B2_FULL; + next_next_READ_OUT <= '0'; + next_b2_buffer <= COMB_DATA_IN; + next_SYN_DATAREADY_OUT <= '1'; + end if; + elsif current_buffer_state = BUFFER_B2_FULL then + if COMB_DATAREADY_IN = '1' and COMB_READ_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; + next_next_READ_OUT <= '0'; + next_b2_buffer <= COMB_DATA_IN; + next_SYN_DATAREADY_OUT <= '1'; + elsif COMB_DATAREADY_IN = '1' and COMB_READ_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 + next_b1_buffer <= COMB_DATA_IN; + next_SYN_DATAREADY_OUT <= '1'; + elsif SYN_READ_IN = '1' then + next_buffer_state <= BUFFER_EMPTY; + end if; + elsif current_buffer_state = BUFFER_B1_FULL then + if COMB_DATAREADY_IN = '1' and COMB_READ_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'; + next_b1_buffer <= COMB_DATA_IN; + next_b2_buffer <= current_b1_buffer; + next_SYN_DATAREADY_OUT <= '1'; + elsif COMB_DATAREADY_IN = '1' and COMB_READ_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; + next_next_READ_OUT <= '0'; + next_b2_buffer <= current_b1_buffer; + next_SYN_DATAREADY_OUT <= '1'; + end if; + end if; +end process COMB; + + + REG : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + current_buffer_state <= BUFFER_EMPTY; + current_got_overflow <= '0'; + current_b1_buffer <= (others => '0'); + current_b2_buffer <= (others => '0'); + current_SYN_DATAREADY_OUT <= '0'; + current_next_READ_OUT <= '0'; + elsif CLK_EN = '1' then + current_buffer_state <= next_buffer_state; + current_got_overflow <= next_got_overflow; + current_b1_buffer <= next_b1_buffer; + current_b2_buffer <= next_b2_buffer; + current_SYN_DATAREADY_OUT <= next_SYN_DATAREADY_OUT; + current_next_READ_OUT <= next_next_READ_OUT; + else + current_buffer_state <= current_buffer_state; + current_got_overflow <= current_got_overflow; + current_b1_buffer <= current_b1_buffer; + current_b2_buffer <= current_b2_buffer; + current_SYN_DATAREADY_OUT <= current_SYN_DATAREADY_OUT; + current_next_READ_OUT <= current_next_READ_OUT; + end if; + end if; + end process; + + + +end trb_net_sbuf_arch; + -- 2.43.0