From ec8b62924bcded75df19ca36d9bd6668d6a0f869 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Tue, 29 Jul 2008 11:36:21 +0000 Subject: [PATCH] added files for addon media interface --- .../scm/dualdatarate_flipflop.vhd | 17 +- .../scm/lattice_scm_dualdatarate_flipflop.vhd | 64 +++ lattice/scm/trb_net_clock_generator.vhd | 11 +- .../scm/trb_net_fifo_16bit_bram_dualport.vhd | 4 +- optical_link/hub.vhd | 2 +- trb_net16_api_base.vhd | 24 +- trb_net16_io_multiplexer.vhd | 22 +- trb_net16_iobuf.vhd | 16 +- trb_net16_med_16_SDR_OS.vhd | 417 ++++++++++++++ trb_net16_obuf.vhd | 13 +- trb_net_med_8bit_slow.vhd | 67 +-- trb_net_std.vhd | 30 +- xilinx/dualdatarate_flipflop.vhd | 45 ++ xilinx/dualdatarate_flipflop_arch.vhd | 27 - xilinx/trb_net_clock_generator.vhd | 62 ++ .../trb_net_fifo_16bit_bram_dualport_arch.vhd | 530 +----------------- xilinx/virtex4/xilinx_fifo_18x1k.vhd | 146 +++++ xilinx/virtex4/xilinx_fifo_dualport_18x1k.vhd | 142 +++++ xilinx/virtex4/xilinx_fifo_dualport_18x1k.xco | 20 +- 19 files changed, 997 insertions(+), 662 deletions(-) rename dualdatarate_flipflop.vhd => lattice/scm/dualdatarate_flipflop.vhd (69%) create mode 100644 lattice/scm/lattice_scm_dualdatarate_flipflop.vhd create mode 100644 trb_net16_med_16_SDR_OS.vhd create mode 100644 xilinx/dualdatarate_flipflop.vhd delete mode 100644 xilinx/dualdatarate_flipflop_arch.vhd create mode 100644 xilinx/trb_net_clock_generator.vhd create mode 100644 xilinx/virtex4/xilinx_fifo_18x1k.vhd create mode 100644 xilinx/virtex4/xilinx_fifo_dualport_18x1k.vhd diff --git a/dualdatarate_flipflop.vhd b/lattice/scm/dualdatarate_flipflop.vhd similarity index 69% rename from dualdatarate_flipflop.vhd rename to lattice/scm/dualdatarate_flipflop.vhd index eb59727..e4353cd 100644 --- a/dualdatarate_flipflop.vhd +++ b/lattice/scm/dualdatarate_flipflop.vhd @@ -3,11 +3,11 @@ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -library unisim; -use UNISIM.VComponents.all; - +library SCM; +use SCM.COMPONENTS.all; entity dualdatarate_flipflop is +--1 clock, no CE, PRE for Lattice SCM generic( WIDTH : integer := 1 ); @@ -24,3 +24,14 @@ entity dualdatarate_flipflop is --ddr output (must be connected to an OBUF) ); end entity dualdatarate_flipflop; + +architecture dualdatarate_flipflop_arch of dualdatarate_flipflop is + +begin + gen_ddrs : for i in 0 to WIDTH-1 generate + ud_0: ODDRXA + port map (DA=>D0(i), DB=>D1(i), CLK=>C0, RST=>CLR, + Q=>Q(i)); + end generate; + +end architecture; \ No newline at end of file diff --git a/lattice/scm/lattice_scm_dualdatarate_flipflop.vhd b/lattice/scm/lattice_scm_dualdatarate_flipflop.vhd new file mode 100644 index 0000000..f36933d --- /dev/null +++ b/lattice/scm/lattice_scm_dualdatarate_flipflop.vhd @@ -0,0 +1,64 @@ +-- VHDL netlist generated by SCUBA ispLever_v71_PROD_Build (58) +-- Module Version: 3.4 +--/local/lattice/ispLever7.1/isptools/ispfpga/bin/lin/scuba -w -n lattice_scm_dualdatarate_flipflop -lang vhdl -synth synplify -bus_exp 7 -bb -arch or5s00 -type iol -mode out -width 1 -reg ddr -gear 1 -cmode 0 -ocmode 0 -e + +-- Wed Jul 23 17:12:27 2008 + +library IEEE; +use IEEE.std_logic_1164.all; +-- synopsys translate_off +library SCM; +use SCM.COMPONENTS.all; +-- synopsys translate_on + +entity lattice_scm_dualdatarate_flipflop is + port ( + Data: in std_logic_vector(1 downto 0); + Clk: in std_logic; + Rst: in std_logic; + Q: out std_logic_vector(0 downto 0)); + attribute dont_touch : string; + attribute dont_touch of lattice_scm_dualdatarate_flipflop : entity is "true"; +end lattice_scm_dualdatarate_flipflop; + +architecture Structure of lattice_scm_dualdatarate_flipflop is + + -- internal signal declarations + signal buf_Q0: std_logic; + + -- local component declarations + component OB + port (I: in std_logic; O: out std_logic); + end component; + component ODDRXA + port (DA: in std_logic; DB: in std_logic; CLK: in std_logic; + RST: in std_logic; Q: out std_logic); + end component; + attribute CLKMODE : string; + attribute LSRMODE : string; + attribute CLKMODE of ud_0 : label is "ECLK"; + attribute LSRMODE of ud_0 : label is "LOCAL"; + attribute syn_noprune : boolean; + attribute syn_noprune of Structure : architecture is true; + +begin + -- component instantiation statements + ud_0: ODDRXA + port map (DA=>Data(0), DB=>Data(1), CLK=>Clk, RST=>Rst, + Q=>buf_Q0); + + buf_Q0_out_inst: OB + port map (I=>buf_Q0, O=>Q(0)); + +end Structure; + +-- synopsys translate_off +library SCM; +configuration Structure_CON of lattice_scm_dualdatarate_flipflop is + for Structure + for all:OB use entity SCM.OB(V); end for; + for all:ODDRXA use entity SCM.ODDRXA(V); end for; + end for; +end Structure_CON; + +-- synopsys translate_on diff --git a/lattice/scm/trb_net_clock_generator.vhd b/lattice/scm/trb_net_clock_generator.vhd index 67b4c0d..c79d90a 100644 --- a/lattice/scm/trb_net_clock_generator.vhd +++ b/lattice/scm/trb_net_clock_generator.vhd @@ -9,8 +9,11 @@ use work.trb_net_std.all; entity trb_net_clock_generator is generic( FREQUENCY_IN : real := 100.0; + FREQUENCY_OUT : real := 200.0; CLOCK_MULT : integer range 1 to 32 := 3; CLOCK_DIV : integer range 1 to 32 := 1; + CLKIN_DIVIDE_BY_2 : boolean := false; + CLKIN_PERIOD : real := 10.0 ); port( RESET : in std_logic; @@ -32,7 +35,7 @@ architecture trb_net_clock_generator_arch of trb_net_clock_generator is begin - gen_3x : if CLOCK_MULT = 3 and CLOCK_DIV = 1 and FREQUENCY_IN = 100.0 generate + gen_3x : if FREQUENCY_OUT = 200.0 and FREQUENCY_IN = 100.0 generate -- parameterized module component instance CLK_GEN : lattice_scm_clock_300 @@ -40,14 +43,14 @@ begin clk =>CLK_IN, clkop=>CLK_OUT, clkos=>open, - lock =>lock + lock =>locked ); end generate; - gen_none : if CLOCK_MULT /= 3 or CLOCK_DIV /= 1 or FREQUENCY_IN /= 100.0 generate + gen_none : if FREQUENCY_OUT = 300.0 or FREQUENCY_IN /= 100.0 generate CLK_OUT <= CLK_IN; LOCKED <= '0'; end generate; -end architecture; \ No newline at end of file +end architecture; diff --git a/lattice/scm/trb_net_fifo_16bit_bram_dualport.vhd b/lattice/scm/trb_net_fifo_16bit_bram_dualport.vhd index 30b9a4d..0a140ae 100644 --- a/lattice/scm/trb_net_fifo_16bit_bram_dualport.vhd +++ b/lattice/scm/trb_net_fifo_16bit_bram_dualport.vhd @@ -19,7 +19,7 @@ entity trb_net_fifo_16bit_bram_dualport is read_data_out: OUT std_logic_vector(17 downto 0); full_out: OUT std_logic; empty_out: OUT std_logic; - fifostatus_out: OUT std_logic_vector(3 downto 0); --counter for 1/16th of fifo + fifostatus_out: OUT std_logic_vector(3 downto 0); valid_read_out: OUT std_logic; almost_empty_out:OUT std_logic; almost_full_out :OUT std_logic @@ -54,5 +54,7 @@ BEGIN AlmostFull => almost_full_out ); +fifostatus_out <= (others => '0'); +valid_read_out <= '0'; end architecture trb_net_fifo_16bit_bram_dualport_arch; diff --git a/optical_link/hub.vhd b/optical_link/hub.vhd index b05e033..d6db47a 100644 --- a/optical_link/hub.vhd +++ b/optical_link/hub.vhd @@ -13,7 +13,7 @@ use work.trb_net16_hub_func.all; -- use sc.components.all; entity hub is generic ( - HOW_MANY_CHANNELS : integer range 2 to c_MAX_MII_PER_HUB := 2 + HOW_MANY_CHANNELS : integer range 2 to c_MAX_MII_PER_HUB := 4 ); port ( LVDS_CLK_200P : in std_logic; diff --git a/trb_net16_api_base.vhd b/trb_net16_api_base.vhd index bafced1..1fefd43 100644 --- a/trb_net16_api_base.vhd +++ b/trb_net16_api_base.vhd @@ -453,7 +453,7 @@ begin if rising_edge(CLK) then if RESET = '1' then sbuf_free <= '0'; - else + elsif CLK_EN = '1' then sbuf_free <= sbuf_next_READ or INT_MASTER_READ_IN; end if; end if; @@ -511,7 +511,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then sbuf_to_apl_free <= '0'; - else + elsif CLK_EN = '1' then sbuf_to_apl_free <= sbuf_to_apl_next_READ; end if; end if; @@ -544,7 +544,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' or fifo_to_apl_packet_num_out = "11" then saved_fifo_to_apl_packet_type <= TYPE_ILLEGAL; - elsif fifo_to_apl_packet_num_out = "00" then + elsif fifo_to_apl_packet_num_out = "00" and CLK_EN = '1' then saved_fifo_to_apl_packet_type <= fifo_to_apl_data_out(2 downto 0); end if; end if; @@ -605,7 +605,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then master_counter <= (others => '0'); - elsif next_INT_MASTER_DATAREADY_OUT = '1' then + elsif next_INT_MASTER_DATAREADY_OUT = '1' and CLK_EN = '1' then master_counter <= master_counter + 1; end if; end if; @@ -620,7 +620,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then fifo_to_apl_read_before <= '0'; - else + elsif CLK_EN = '1' then if fifo_to_apl_read = '1' then fifo_to_apl_read_before <= '1'; elsif sbuf_to_apl_free = '1' or throw_away = '1' then @@ -635,7 +635,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then fifo_to_int_read_before <= '0'; - else + elsif CLK_EN = '1' then if fifo_to_int_read = '1' then fifo_to_int_read_before <= '1'; elsif next_INT_MASTER_DATAREADY_OUT = '1' and master_counter /= "00" then --implies sbuf_free @@ -654,7 +654,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; fifo_to_apl_packet_num_out, state_to_apl, reg_APL_TYP_OUT, reg_APL_PACKET_NUM_OUT, sbuf_to_apl_free, INT_SLAVE_DATA_IN, INT_SLAVE_PACKET_NUM_IN, APL_MY_ADDRESS_IN, reg_APL_DATAREADY_OUT, slave_running, fifo_to_apl_read_before, throw_away,state_to_int, - saved_fifo_to_apl_packet_type ) + saved_fifo_to_apl_packet_type,master_start) begin reg_INT_SLAVE_READ_OUT <= not fifo_to_apl_full; fifo_to_apl_write <= reg_INT_SLAVE_READ_OUT and INT_SLAVE_DATAREADY_IN; @@ -812,7 +812,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; send_trm_wrong_addr <= '0'; sequence_counter <= (others => '0'); fifo_was_not_empty <= '0'; - else + elsif CLK_EN = '1' then state_to_apl <= next_state_to_apl; state_to_int <= next_state_to_int; --reg_INT_SLAVE_READ_OUT <= next_INT_SLAVE_READ_OUT; @@ -830,7 +830,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; --------------------------------------- process(CLK) begin - if rising_edge(CLK) then + if rising_edge(CLK) and CLK_EN = '1' then if slave_start = '1' then endpoint_reached <= '1'; elsif master_end = '1' or RESET = '1' then @@ -851,7 +851,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then combined_header_F2 <= (others => '1'); - elsif current_fifo_to_apl_packet_type = TYPE_HDR and fifo_to_apl_packet_num_out = "01" then + elsif current_fifo_to_apl_packet_type = TYPE_HDR and fifo_to_apl_packet_num_out = "01" and CLK_EN = '1' then combined_header_F2 <= fifo_to_apl_data_out; end if; end if; @@ -887,7 +887,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if rising_edge(CLK) then if RESET = '1' then APL_RUN_OUT <= '0'; - else + elsif CLK_EN = '1' then if API_TYPE = 0 then if slave_start = '1' then APL_RUN_OUT <= '1'; @@ -911,7 +911,7 @@ INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT; if RESET = '1' then master_running <= '0'; slave_running <= '0'; - else + elsif CLK_EN = '1' then if master_start = '1' then master_running <= '1'; elsif master_end = '1' then diff --git a/trb_net16_io_multiplexer.vhd b/trb_net16_io_multiplexer.vhd index c1ed641..49979d2 100644 --- a/trb_net16_io_multiplexer.vhd +++ b/trb_net16_io_multiplexer.vhd @@ -16,12 +16,12 @@ entity trb_net16_io_multiplexer is CLK_EN : in std_logic; -- Media direction port - MED_DATAREADY_IN: in STD_LOGIC; + MED_DATAREADY_IN: in STD_LOGIC; MED_DATA_IN: in STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); MED_PACKET_NUM_IN: in STD_LOGIC_VECTOR (1 downto 0); MED_READ_OUT: out STD_LOGIC; - MED_DATAREADY_OUT: out STD_LOGIC; + MED_DATAREADY_OUT: out STD_LOGIC; MED_DATA_OUT: out STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); MED_PACKET_NUM_OUT: out STD_LOGIC_VECTOR (1 downto 0); MED_READ_IN: in STD_LOGIC; @@ -85,14 +85,14 @@ architecture trb_net16_io_multiplexer_arch of trb_net16_io_multiplexer is CLK_EN : in std_logic; INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0); RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0); - ENABLE : in std_logic; + ENABLE : in std_logic; CTRL: in STD_LOGIC_VECTOR (31 downto 0) ); end component; signal demux_next_READ, current_demux_READ : STD_LOGIC_VECTOR ((2**c_MUX_WIDTH-1)-1 downto 0); signal next_demux_dr, next_demux_dr_tmp, demux_dr_tmp: STD_LOGIC_VECTOR (2**(c_MUX_WIDTH-1)-1 downto 0); - signal current_MED_READ_OUT, next_MED_READ_OUT: STD_LOGIC; + signal current_MED_READ_OUT, next_MED_READ_OUT: STD_LOGIC; signal final_INT_READ_OUT: STD_LOGIC_VECTOR ((2**c_MUX_WIDTH)-1 downto 0); --signal tmp_tmp_INT_READ_OUT: STD_LOGIC_VECTOR ((2**c_MUX_WIDTH)-1 downto 0); signal mux_read, mux_enable, mux_next_READ: STD_LOGIC; @@ -135,7 +135,7 @@ architecture trb_net16_io_multiplexer_arch of trb_net16_io_multiplexer is end if; end process; end generate; - + INT_DATA_OUT <= buf_INT_DATA_OUT; INT_PACKET_NUM_OUT <= buf_INT_PACKET_NUM_OUT; @@ -153,7 +153,7 @@ architecture trb_net16_io_multiplexer_arch of trb_net16_io_multiplexer is -- generate the READ_OUT next_MED_READ_OUT <= '1'; --and_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'); @@ -179,8 +179,12 @@ architecture trb_net16_io_multiplexer_arch of trb_net16_io_multiplexer is -- INPUT_IN => MED_DATA_IN(4+c_MUX_WIDTH-2 downto 4), -- RESULT_OUT => next_demux_dr_tmp -- this will have a 1 in ANY case -- ); - next_demux_dr_tmp <= conv_std_logic_vector(2**conv_integer(MED_DATA_IN(4+c_MUX_WIDTH-2 downto 4)),2**(c_MUX_WIDTH-1)); - + gen_no_demux : if c_MUX_WIDTH = 1 generate + next_demux_dr_tmp <= "1"; + end generate; + gen_demux : if c_MUX_WIDTH /= 1 generate + next_demux_dr_tmp <= conv_std_logic_vector(2**conv_integer(MED_DATA_IN(4+c_MUX_WIDTH-2 downto 4)),2**(c_MUX_WIDTH-1)); + end generate; keep_valid_demux : process(CLK) begin if rising_edge(CLK) then @@ -208,7 +212,7 @@ architecture trb_net16_io_multiplexer_arch of trb_net16_io_multiplexer is ------------------------------------------------------------------------------- -- MUX part with arbitration scheme ------------------------------------------------------------------------------- -ARBITER: trb_net_priority_arbiter +ARBITER: trb_net_priority_arbiter generic map ( WIDTH => 2**c_MUX_WIDTH ) diff --git a/trb_net16_iobuf.vhd b/trb_net16_iobuf.vhd index 1cbf63f..7d3c3c9 100644 --- a/trb_net16_iobuf.vhd +++ b/trb_net16_iobuf.vhd @@ -133,8 +133,8 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is ); port( -- Misc - CLK : in std_logic; - RESET : in std_logic; + CLK : in std_logic; + RESET : in std_logic; CLK_EN : in std_logic; -- Media direction port MED_DATAREADY_IN : in std_logic; @@ -164,8 +164,8 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is ); port( -- Misc - CLK : in std_logic; - RESET : in std_logic; + CLK : in std_logic; + RESET : in std_logic; CLK_EN : in std_logic; -- Media direction port MED_DATAREADY_IN: in std_logic; @@ -183,7 +183,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is STAT_BUFFER: out std_logic_vector (31 downto 0) ); end component; - + -- internal signals for the INITIBUF signal IBUF_error: STD_LOGIC_VECTOR (2 downto 0); -- error watch needed! signal IBUF_stat_buffer : STD_LOGIC_VECTOR (31 downto 0); @@ -196,7 +196,7 @@ begin ibuf_dataready_in <= MED_DATAREADY_IN;-- or MED_REPLY_DATAREADY_IN; MED_READ_OUT <= ibuf_read_out; -- MED_REPLY_READ_OUT <= ibuf_read_out; - + IBUF : trb_net16_ibuf generic map ( DEPTH => IBUF_DEPTH, @@ -355,7 +355,7 @@ begin STAT_IBUF_BUFFER <= IBUF_stat_buffer; -- build the registers according to the wiki page - -- STAT_BUFFER(15 downto 0) + -- STAT_BUFFER(15 downto 0) -- STAT_INIT_BUFFER(8 downto 0) <= INITIBUF_stat_buffer(8 downto 0); -- STAT_INIT_BUFFER(11 downto 9) <= INITOBUF_stat_buffer(17 downto 15); -- STAT_INIT_BUFFER(13 downto 12) <= (others => '0'); @@ -374,5 +374,5 @@ STAT_IBUF_BUFFER <= IBUF_stat_buffer; REPLYOBUF_ctrl_buffer(31 downto 10) <= (others => '0'); STAT_GEN <= (others => '0'); - + end architecture; diff --git a/trb_net16_med_16_SDR_OS.vhd b/trb_net16_med_16_SDR_OS.vhd new file mode 100644 index 0000000..bebf4ca --- /dev/null +++ b/trb_net16_med_16_SDR_OS.vhd @@ -0,0 +1,417 @@ +--media interface with 16 data lines, single data rate and oversampling of RX input +--oversampling running at 250 MHz + + + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net16_med_16_SDR_OS is + generic( + TRANSMISSION_CLOCK_DIV: integer range 1 to 10 := 1 + ); + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + + INT_DATAREADY_OUT : out std_logic; + INT_DATA_OUT : out std_logic_vector (c_DATA_WIDTH-1 downto 0); + INT_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH-1 downto 0); + INT_READ_IN : in std_logic; + INT_ERROR_OUT : out std_logic_vector (2 downto 0); + + INT_DATAREADY_IN : in std_logic; + INT_DATA_IN : in std_logic_vector (c_DATA_WIDTH-1 downto 0); + INT_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH-1 downto 0); + INT_READ_OUT : out std_logic; + + -- Media direction port + TX_DATA_OUT : out std_logic_vector (15 downto 0); + TX_CLK_OUT : out std_logic; + TX_CTRL_OUT : out std_logic_vector (3 downto 0); + RX_DATA_IN : in std_logic_vector (15 downto 0); + RX_CLK_IN : in std_logic; + RX_CTRL_IN : in std_logic_vector (3 downto 0); + + -- Status and control port + STAT_OP: out std_logic_vector (15 downto 0); + CTRL_OP: in std_logic_vector (15 downto 0); + + STAT: out std_logic_vector (31 downto 0); + CTRL: in std_logic_vector (31 downto 0) + ); +end entity; + +architecture trb_net16_med_16_SDR_OS_arch of trb_net16_med_16_SDR_OS is + component trb_net_clock_generator is + generic( + FREQUENCY_IN : real; + FREQUENCY_OUT : real; + CLOCK_MULT : integer range 1 to 32; + CLOCK_DIV : integer range 1 to 32; + CLKIN_DIVIDE_BY_2 : boolean; + CLKIN_PERIOD : real + ); + port( + RESET : in std_logic; + CLK_IN : in std_logic; + CLK_OUT : out std_logic; + LOCKED : out std_logic + ); + end component; + + component trb_net_fifo_16bit_bram_dualport is + generic( + USE_STATUS_FLAGS : integer := c_YES + ); + port ( + read_clock_in: IN std_logic; + write_clock_in: IN std_logic; + read_enable_in: IN std_logic; + write_enable_in: IN std_logic; + fifo_gsr_in: IN std_logic; + write_data_in: IN std_logic_vector(17 downto 0); + read_data_out: OUT std_logic_vector(17 downto 0); + full_out: OUT std_logic; + empty_out: OUT std_logic; + fifostatus_out: OUT std_logic_vector(3 downto 0); + valid_read_out: OUT std_logic; + almost_empty_out:OUT std_logic; + almost_full_out :OUT std_logic + ); + end component; + + component dualdatarate_flipflop is + --1 clock, no CE, PRE for Lattice SCM + generic( + WIDTH : integer := 1 + ); + port( + C0 : in std_logic; + C1 : in std_logic; + CE : in std_logic; + CLR : in std_logic; + D0 : in std_logic_vector(WIDTH-1 downto 0); + D1 : in std_logic_vector(WIDTH-1 downto 0); + PRE : in std_logic; + Q : out std_logic_vector(WIDTH-1 downto 0) + ); + end component; + + signal RECV_CLK, recv_clk_locked : std_logic; + signal reg_RX_CLK, buf_RX_CLK, last_RX_CLK : std_logic; + signal reg_RX_CTRL, buf_RX_CTRL : std_logic_vector(3 downto 0); + signal reg_RX_DATA, buf_RX_DATA : std_logic_vector(15 downto 0); + + signal rx_datavalid : std_logic; + signal rx_first_packet : std_logic; + signal rx_reset : std_logic; + signal rx_parity : std_logic; + signal rx_parity_match : std_logic; + + signal rx_fifo_read_enable : std_logic; + signal rx_fifo_write_enable, next_rx_fifo_write_enable: std_logic; + signal rx_fifo_data_in, next_rx_fifo_data_in : std_logic_vector(17 downto 0); + signal rx_fifo_data_out : std_logic_vector(17 downto 0); + signal rx_fifo_full : std_logic; + signal rx_fifo_empty : std_logic; + + + signal buf_INT_DATAREADY_OUT : std_logic; + + signal rx_packet_counter : std_logic_vector(1 downto 0); + signal wait_for_startup : std_logic; + signal wait_for_startup_slow : std_logic; + signal rx_CLK_counter : std_logic_vector(4 downto 0); + signal rx_clock_detect : std_logic; + + signal med_reset : std_logic; + + signal tx_datavalid, tx_first_packet, tx_reset, tx_parity : std_logic; + signal buf_INT_DATA_IN : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal buf_INT_READ_OUT : std_logic; + signal tx_clock_enable : std_logic; + signal next_tx_reset : std_logic; + signal buf_tx_reset : std_logic; + signal buf_tx_clk, buf2_tx_clk : std_logic; + signal C_D0, C_D1,Q : std_logic_vector(0 downto 0); + signal recv_clk_real_locked : std_logic; + signal locked_counter : std_logic_vector(19 downto 0); + + +begin + + +--Transmitter (full speed only) +------------------------- + INT_READ_OUT <= buf_INT_READ_OUT; + buf_INT_READ_OUT <= not wait_for_startup_slow and not buf_tx_reset; + + TX_DATA_OUT <= buf_INT_DATA_IN; + TX_CTRL_OUT(0) <= tx_datavalid; + TX_CTRL_OUT(1) <= tx_first_packet; + TX_CTRL_OUT(2) <= tx_reset; + TX_CTRL_OUT(3) <= tx_parity; + + tx_clock_enable <= not RESET; + + next_tx_reset <= CTRL_OP(15) or (recv_clk_real_locked and wait_for_startup_slow); + +-- clk_ddr : dualdatarate_flipflop +-- port map( +-- C0 => CLK, +-- C1 => not CLK, +-- CE => '1', +-- CLR => not tx_clock_enable, +-- D0 => C_D0, +-- D1 => C_D1, +-- PRE => '0', +-- Q => Q +-- ); +-- C_D0(0) <= buf_tx_clk; +-- C_D1(0) <= buf_tx_clk; +-- TX_CLK_OUT <= Q(0); +--TX_CLK_OUT <= buf_tx_clk; + + process(CLK) + begin + if falling_edge(CLK) then + TX_CLK_OUT <= buf_tx_clk; + end if; + end process; + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or med_reset = '1' then + tx_datavalid <= '0'; + tx_reset <= '1'; + buf_tx_reset <= '1'; + buf_INT_DATA_IN <= (others => '0'); + tx_first_packet <= '0'; + tx_parity <= '0'; + buf_tx_clk <= '0'; + buf2_tx_clk <= '0'; + else + buf_INT_DATA_IN <= INT_DATA_IN; + tx_datavalid <= INT_DATAREADY_IN and buf_INT_READ_OUT; + tx_first_packet <= not or_all(INT_PACKET_NUM_IN); + tx_reset <= buf_tx_reset; + buf_tx_reset <= next_tx_reset; + tx_parity <= xor_all(INT_DATA_IN); + buf_tx_clk <= not buf_tx_clk; +-- buf2_tx_clk <= buf_tx_clk; + end if; + end if; + end process; + + + +--Receiver +------------------------- + RECV_CLOCK_GEN : trb_net_clock_generator + generic map( + FREQUENCY_IN => 100.0, + FREQUENCY_OUT => 200.0, + CLOCK_MULT => 2, + CLOCK_DIV => 1, + CLKIN_DIVIDE_BY_2 => false, + CLKIN_PERIOD => 20.0 + ) + port map( + RESET => RESET, + CLK_IN => CLK, + CLK_OUT => RECV_CLK, + LOCKED => recv_clk_locked + ); + +process(CLK) + begin + if rising_edge(CLK) then + if recv_clk_locked = '0' then + locked_counter <= (others => '0'); + recv_clk_real_locked <= '0'; + else + if locked_counter /= x"0000F" then + locked_counter <= locked_counter + 1; + else + recv_clk_real_locked <= '1'; + end if; + end if; + end if; + end process; + + RX_INPUT_REG : process(RECV_CLK) + begin + if rising_edge(RECV_CLK) then + reg_RX_CLK <= RX_CLK_IN; + reg_RX_CTRL <= RX_CTRL_IN; + reg_RX_DATA <= RX_DATA_IN; + end if; + end process; + + RX_REG : process(RECV_CLK, recv_clk_real_locked) + begin + if recv_clk_real_locked = '0' then + buf_RX_CTRL <= (others => '0'); + buf_RX_CLK <= '0'; + last_RX_CLK <= '0'; + buf_RX_DATA <= reg_RX_DATA; + elsif rising_edge(RECV_CLK) then + buf_RX_CLK <= reg_RX_CLK; + buf_RX_DATA <= reg_RX_DATA; + buf_RX_CTRL <= reg_RX_CTRL; + last_RX_CLK <= buf_RX_CLK; + end if; + end process; + + rx_datavalid <= buf_RX_CTRL(0); + rx_first_packet <= buf_RX_CTRL(1); + rx_reset <= buf_RX_CTRL(2); + rx_parity <= buf_RX_CTRL(3); + + rx_parity_match <= xor_all(rx_parity & buf_RX_DATA); + next_rx_fifo_write_enable <= (buf_RX_CLK xor last_RX_CLK) and rx_datavalid; + next_rx_fifo_data_in <= rx_first_packet & rx_parity_match & buf_RX_DATA; + + reg_fifo_in : process(RECV_CLK) + begin + if rising_edge(RECV_CLK) then + rx_fifo_write_enable <= next_rx_fifo_write_enable; + rx_fifo_data_in <= next_rx_fifo_data_in; + end if; + end process; + + RX_FIFO : trb_net_fifo_16bit_bram_dualport + port map( + read_clock_in => CLK, + write_clock_in => RECV_CLK, + read_enable_in => rx_fifo_read_enable, + write_enable_in => rx_fifo_write_enable, + fifo_gsr_in => med_reset, + write_data_in => rx_fifo_data_in, + read_data_out => rx_fifo_data_out, + full_out => rx_fifo_full, + empty_out => rx_fifo_empty, + fifostatus_out => open, + valid_read_out => open, + almost_empty_out => open, + almost_full_out => open + ); + + rx_fifo_read_enable <= INT_READ_IN; + + INT_DATA_OUT <= rx_fifo_data_out(15 downto 0); + INT_PACKET_NUM_OUT <= rx_packet_counter; + INT_DATAREADY_OUT <= buf_INT_DATAREADY_OUT; + + packet_counter_p : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or med_reset = '1' then + rx_packet_counter <= "00"; + elsif buf_INT_DATAREADY_OUT = '1' then + rx_packet_counter <= rx_packet_counter + 1; + end if; + end if; + end process; + + + rx_dataready_p : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or med_reset = '1' then + buf_INT_DATAREADY_OUT <= '0'; + else + buf_INT_DATAREADY_OUT <= rx_fifo_read_enable and not rx_fifo_empty; + end if; + end if; + end process; + + +--monitor link +------------------------- + process(CLK) + begin + if rising_edge(CLK) then + wait_for_startup_slow <= wait_for_startup; + end if; + end process; + + process(RECV_CLK, recv_clk_real_locked,med_reset) + begin + if recv_clk_real_locked = '0' or med_reset = '1' then + wait_for_startup <= '1'; + elsif rising_edge(RECV_CLK) then + if rx_clock_detect = '0' then + wait_for_startup <= '1'; + elsif rx_reset = '1' and recv_clk_locked = '1' then + wait_for_startup <= '0'; + end if; + end if; + end process; + + + ERROR_OUT_gen : process(CLK) + begin + if rising_edge(CLK) then + if recv_clk_real_locked = '0' then + INT_ERROR_OUT <= ERROR_NC; + elsif (buf_INT_DATAREADY_OUT = '1' and rx_fifo_data_out(16) = '0') then --Parity error + INT_ERROR_OUT <= ERROR_ENCOD; + elsif (rx_packet_counter /= "00" and buf_INT_DATAREADY_OUT = '1' and rx_fifo_data_out(17) = '1') then + INT_ERROR_OUT <= ERROR_FATAL; --Counter error + else + INT_ERROR_OUT <= ERROR_OK; + end if; + end if; + end process; + + + rx_clk_detect_counter: process (RECV_CLK, recv_clk_real_locked) + begin + if recv_clk_real_locked = '0' then + rx_CLK_counter <= (others => '0'); + rx_clock_detect <= '0'; + elsif rising_edge(RECV_CLK) then + if buf_RX_CLK = '1' and last_RX_CLK = '0' then + rx_CLK_counter <= (others => '0'); + rx_clock_detect <= '1'; + elsif rx_CLK_counter /= 31 then + rx_CLK_counter <= rx_CLK_counter + 1; + elsif rx_CLK_counter = 31 then + rx_clock_detect <= '0'; + end if; + end if; + end process; + + +--STAT & CTRL Ports +------------------------- + STAT_OP(14 downto 0) <= (others => '0'); + STAT_OP(15) <= '1' when rx_reset = '1' and wait_for_startup_slow = '0' else '0'; + + STAT(11) <= RECV_CLK; + STAT(10) <= recv_clk_real_locked; + STAT(9) <= rx_reset; + STAT(8) <= buf_RX_CLK xor last_RX_CLK; + STAT(7) <= recv_clk_locked; + STAT(6) <= wait_for_startup; + STAT(5) <= rx_first_packet; + STAT(4) <= buf_tx_clk; --not or_all(INT_PACKET_NUM_IN); --tx_first_packet; + STAT(3) <= rx_datavalid; + STAT(2) <= next_tx_reset; + STAT(1) <= buf_RX_CLK; + + STAT(31 downto 12) <= (others => '0'); + + med_reset <= RESET or CTRL_OP(15); + +end architecture; \ No newline at end of file diff --git a/trb_net16_obuf.vhd b/trb_net16_obuf.vhd index 38e99b1..6654c7f 100644 --- a/trb_net16_obuf.vhd +++ b/trb_net16_obuf.vhd @@ -19,8 +19,8 @@ entity trb_net16_obuf is ); port( -- Misc - CLK : in std_logic; - RESET : in std_logic; + CLK : in std_logic; + RESET : in std_logic; CLK_EN : in std_logic; -- Media direction port MED_DATAREADY_OUT : out std_logic; @@ -82,13 +82,13 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is STD_LOGIC_VECTOR (15 downto 0); signal comb_dataready, comb_next_read, comb_read ,sbuf_free: STD_LOGIC; signal reg_INT_READ_OUT , next_INT_READ_OUT:STD_LOGIC; - + signal next_SEND_ACK_IN, reg_SEND_ACK_IN : STD_LOGIC; signal send_ACK, send_EOB, send_DATA : STD_LOGIC; signal CURRENT_DATA_COUNT : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0); -- signal max_DATA_COUNT, next_max_DATA_COUNT : STD_LOGIC_VECTOR (15 downto 0); - signal max_DATA_COUNT_minus_one, next_max_DATA_COUNT_minus_one : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0); + signal max_DATA_COUNT_minus_one : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0); signal TRANSMITTED_BUFFERS : STD_LOGIC_VECTOR (1 downto 0); signal increase_TRANSMITTED_BUFFERS, decrease_TRANSMITTED_BUFFERS : STD_LOGIC; @@ -96,7 +96,7 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is signal REC_BUFFER_SIZE_IN : STD_LOGIC_VECTOR (3 downto 0); signal SEND_ACK_IN : STD_LOGIC; signal GOT_ACK_IN : STD_LOGIC; - + signal transfer_counter : std_logic_vector(1 downto 0); signal saved_packet_type : std_logic_vector(2 downto 0); signal reg_SEND_ACK_IN_2,next_SEND_ACK_IN_2 : std_logic; @@ -181,7 +181,6 @@ begin send_DATA <= '1'; CURRENT_DATA_COUNT <= (others => '0'); max_DATA_COUNT_minus_one <= (others => '0'); - next_max_DATA_COUNT_minus_one <= (others => '0'); end generate; GENERATE_WORDS : process(transfer_counter, SEND_BUFFER_SIZE_IN, INT_DATA_IN, @@ -407,7 +406,7 @@ begin end if; end if; end process; - + end generate; diff --git a/trb_net_med_8bit_slow.vhd b/trb_net_med_8bit_slow.vhd index 759d31f..52e3e1b 100644 --- a/trb_net_med_8bit_slow.vhd +++ b/trb_net_med_8bit_slow.vhd @@ -1,6 +1,6 @@ --This entity provides data transfer (64bit) via a smaller (16bit) Bus --with three bits for debugging (13bit data + 3bit control) ---first 56bit via Bus are for dataword, transmitted Bits 64 downto 56 Bits +--first 56bit via Bus are for dataword, transmitted Bits 64 downto 56 Bits --are for debugging @@ -13,32 +13,32 @@ library work; use work.trb_net_std.all; entity trb_net_med_8bit_slow is - generic( + generic( TRANSMISSION_CLOCK_DIVIDER: integer range 2 to 62 := 2 --even values only! ); port( -- Misc - CLK : in std_logic; - RESET : in std_logic; + CLK : in std_logic; + RESET : in std_logic; CLK_EN : in std_logic; -- Internal direction port (MII) - -- do not change this interface!!! + -- do not change this interface!!! -- 1st part: from the medium to the internal logic (trbnet) INT_DATAREADY_OUT: out STD_LOGIC; --Data word is reconstructed from media --and ready to be read out (the IOBUF MUST read) INT_DATA_OUT: out STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word INT_PACKET_NUM_OUT:out STD_LOGIC_VECTOR (c_NUM_WIDTH-1 downto 0); - INT_READ_IN: in STD_LOGIC; + INT_READ_IN: in STD_LOGIC; INT_ERROR_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Status bits -- 2nd part: from the internal logic (trbnet) to the medium - INT_DATAREADY_IN: in STD_LOGIC; -- Data word is offered for the Media + INT_DATAREADY_IN: in STD_LOGIC; -- Data word is offered for the Media INT_DATA_IN: in STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word INT_PACKET_NUM_IN: in STD_LOGIC_VECTOR (c_NUM_WIDTH-1 downto 0); INT_READ_OUT: out STD_LOGIC; -- offered word is read INT_ERROR_IN: in STD_LOGIC_VECTOR (2 downto 0); -- Status bits - -- (end do not change this interface!!!) + -- (end do not change this interface!!!) + - -- Media direction port -- in this case for the cable => 32 lines in total MED_DATA_OUT: out STD_LOGIC_VECTOR (15 downto 0); -- Data word @@ -53,9 +53,9 @@ entity trb_net_med_8bit_slow is --STAT(27 downto 24): packets_out (mod 16) --STAT(11 downto 8): INT2MED state --STAT(15 downto 12): MED2INT state - - CTRL: in STD_LOGIC_VECTOR (31 downto 0) - --CTRL(24..31) -> lvds-data(63 downto 56) via lvds + + CTRL: in STD_LOGIC_VECTOR (31 downto 0) + --CTRL(24..31) -> lvds-data(63 downto 56) via lvds --once for each packet ); end entity trb_net_med_8bit_slow; @@ -78,7 +78,7 @@ architecture trb_net_med_8bit_slow_arch of trb_net_med_8bit_slow is signal my_error,next_my_error : std_logic_vector(2 downto 0); signal fatal_error, media_not_connected : std_logic; signal next_media_not_connected : std_logic; - signal transmission_clk_Counter : std_logic_vector(4 downto 0); + signal transmission_clk_Counter : std_logic_vector(4 downto 0); signal next_transmission_clk_Counter : std_logic_vector(4 downto 0); signal next_TRANSMISSION_CLK: std_logic; signal buf_CTRL, next_STAT, buf_STAT : std_logic_vector(31 downto 0); @@ -90,7 +90,7 @@ architecture trb_net_med_8bit_slow_arch of trb_net_med_8bit_slow is signal packets_in_counter, next_packets_in_counter: std_logic_vector(7 downto 0); signal packets_in_compl_counter, next_packets_in_compl_counter: std_logic_vector(3 downto 0); signal packets_out_counter, next_packets_out_counter: std_logic_vector(3 downto 0); - + signal last_MED_TRANSMISSION_CLK_IN : std_logic; signal reg_MED_DATA_IN : std_logic_vector(7 downto 0); signal reg_MED_TRANSMISSION_CLK_IN, reg_MED_CARRIER_IN : std_logic; @@ -129,42 +129,17 @@ begin - --CTRL register - -------------------------------- - CTRL_reg: process (CLK,RESET) - begin - if RESET = '1' then - buf_CTRL <= (others => '0'); - elsif rising_edge(CLK) then - buf_CTRL <= CTRL; - else - buf_CTRL <= buf_CTRL; - end if; - end process; - - - --My error bits -------------------------------- - gen_my_error: process(media_not_connected,fatal_error, MED_DATA_IN) - begin - if media_not_connected = '1' or MED_DATA_IN(11) = '0' then - next_my_error <= ERROR_NC; - elsif fatal_error = '1' then - next_my_error <= "011"; - else - next_my_error <= "000"; - end if; - end process; - - reg_my_error: process(CLK,RESET) begin if rising_edge(CLK) then - if RESET = '1' then - my_error <= "000"; + if RESET = '1' or media_not_connected = '1' or MED_DATA_IN(11) = '0' then + my_error <= ERROR_NC; + elsif fatal_error = '1' then + next_my_error <= ERROR_FATAL; else - my_error <= next_my_error; + next_my_error <= ERROR_OK; end if; end if; end process; @@ -222,8 +197,8 @@ begin transCLK_counter: process (this_TRCLK, last_TRCLK, CLK_counter, - buf_MED_DATA_OUT, buf_MED_CARRIER_OUT, - buf_MED_PARITY_OUT, buf_CTRL) + buf_MED_DATA_OUT, buf_MED_CARRIER_OUT, + buf_MED_PARITY_OUT) begin next_media_not_connected <= '0'; if last_TRCLK = '0' and this_TRCLK = '1' then diff --git a/trb_net_std.vhd b/trb_net_std.vhd index 0b93ab6..0b3cb0e 100644 --- a/trb_net_std.vhd +++ b/trb_net_std.vhd @@ -5,18 +5,18 @@ USE IEEE.std_logic_ARITH.ALL; USE IEEE.std_logic_UNSIGNED.ALL; package trb_net_std is - + type channel_config_t is array(0 to 3) of integer; - + -- some basic definitions for the whole network ----------------------------------------------- constant c_DATA_WIDTH : integer := 16; constant c_NUM_WIDTH : integer := 2; - constant c_MUX_WIDTH : integer := 3; --!!! + constant c_MUX_WIDTH : integer := 1; --!!! ---assigning channel names +--assigning channel names constant c_TRG_LVL1_CHANNEL : integer := 0; constant c_TRG_LVL2_CHANNEL : integer := 1; constant c_DATA_CHANNEL : integer := 2; @@ -25,7 +25,7 @@ package trb_net_std is --api_type generic constant c_API_ACTIVE : integer := 1; constant c_API_PASSIVE : integer := 0; - + --sbuf_version generic constant c_SBUF_FULL : integer := 0; constant c_SBUF_FAST : integer := 0; @@ -33,9 +33,9 @@ package trb_net_std is constant c_SBUF_SLOW : integer := 1; constant c_SECURE_MODE : integer := 1; constant c_NON_SECURE_MODE : integer := 0; - + --fifo_depth - constant c_FIFO_NONE : integer := 0; + constant c_FIFO_NONE : integer := 0; constant c_FIFO_2PCK : integer := 1; constant c_FIFO_SMALL : integer := 1; constant c_FIFO_4PCK : integer := 2; @@ -45,7 +45,7 @@ package trb_net_std is constant c_FIFO_BRAM : integer := 6; constant c_FIFO_BIGGEST : integer := 6; constant c_FIFO_INFTY : integer := 7; - + --simple logic constant c_YES : integer := 1; constant c_NO : integer := 0; @@ -61,11 +61,11 @@ package trb_net_std is constant std_TERM_SECURE_MODE : integer := c_NO; constant std_MUX_SECURE_MODE : integer := c_NO; constant std_FORCE_REPLY : integer := c_YES; - constant cfg_USE_CHECKSUM : channel_config_t := (c_NO ,c_YES,c_YES,c_YES); + constant cfg_USE_CHECKSUM : channel_config_t := (c_YES,c_YES,c_YES,c_YES); constant cfg_USE_ACKNOWLEDGE : channel_config_t := (c_YES,c_YES,c_YES,c_YES); constant cfg_FORCE_REPLY : channel_config_t := (c_YES,c_YES,c_YES,c_YES); constant cfg_USE_REPLY_CHANNEL : channel_config_t := (c_YES,c_YES,c_YES,c_YES); - + constant c_MAX_IDLE_TIME_PER_PACKET : integer := 24; --packet types constant TYPE_DAT : std_logic_vector(2 downto 0) := "000"; @@ -107,7 +107,7 @@ package trb_net_std is constant c_write_register_type : std_logic_vector(3 downto 0) := x"9"; constant c_read_multiple_type : std_logic_vector(3 downto 0) := x"A"; constant c_write_multiple_type : std_logic_vector(3 downto 0) := x"B"; - + --function declarations @@ -119,7 +119,7 @@ package trb_net_std is return std_logic; function xor_all (arg : std_logic_vector) return std_logic; - + function get_bit_position (arg : std_logic_vector) return integer; @@ -128,7 +128,7 @@ package trb_net_std is function MAX(x : integer; y : integer) return integer; - + end package trb_net_std; package body trb_net_std is @@ -154,7 +154,7 @@ package body trb_net_std is end loop; -- i return tmp; end function or_all; - + function all_zero (arg : std_logic_vector) return std_logic is variable tmp : std_logic := '1'; @@ -220,6 +220,6 @@ package body trb_net_std is return y; end if; end MAX; - + end package body trb_net_std; diff --git a/xilinx/dualdatarate_flipflop.vhd b/xilinx/dualdatarate_flipflop.vhd new file mode 100644 index 0000000..c0dde0a --- /dev/null +++ b/xilinx/dualdatarate_flipflop.vhd @@ -0,0 +1,45 @@ +--instantiates DualDataRate-Output-Flipflops with generic width + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +library unisim; +use UNISIM.VComponents.all; + +entity dualdatarate_flipflop is + generic( + WIDTH : integer := 1 + ); + port( + C0 : in std_logic; + C1 : in std_logic; --two clocks + CE : in std_logic; --clock enable + CLR : in std_logic; --global clear + D0 : in std_logic_vector(WIDTH-1 downto 0); + D1 : in std_logic_vector(WIDTH-1 downto 0); + --two data inputs + PRE : in std_logic; --global preset + Q : out std_logic_vector(WIDTH-1 downto 0) + --ddr output (must be connected to an OBUF) + ); +end entity dualdatarate_flipflop; + +architecture dualdatarate_flipflop_arch of dualdatarate_flipflop is + +begin + + ddr_ff_gen : for i in 0 to WIDTH-1 generate + ddr_ff : FDDRCPE + port map( + Q => Q(i), + C0 => C0, + C1 => C1, + CE => CE, + CLR => CLR, + D0 => D0(i), + D1 => D1(i), + PRE => PRE + ); + end generate; + +end architecture; \ No newline at end of file diff --git a/xilinx/dualdatarate_flipflop_arch.vhd b/xilinx/dualdatarate_flipflop_arch.vhd deleted file mode 100644 index 62f71bd..0000000 --- a/xilinx/dualdatarate_flipflop_arch.vhd +++ /dev/null @@ -1,27 +0,0 @@ ---instantiates DualDataRate-Output-Flipflops with generic width - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; -library unisim; -use UNISIM.VComponents.all; - -architecture dualdatarate_flipflop_arch of dualdatarate_flipflop is - -begin - - ddr_ff_gen : for i in 0 to WIDTH-1 generate - ddr_ff : FDDRCPE - port map( - Q => Q(i), - C0 => C0, - C1 => C1, - CE => CE, - CLR => CLR, - D0 => D0(i), - D1 => D1(i), - PRE => PRE - ); - end generate; - -end architecture; \ No newline at end of file diff --git a/xilinx/trb_net_clock_generator.vhd b/xilinx/trb_net_clock_generator.vhd new file mode 100644 index 0000000..c55cee4 --- /dev/null +++ b/xilinx/trb_net_clock_generator.vhd @@ -0,0 +1,62 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; +library work; +use work.trb_net_std.all; +library unisim; +use UNISIM.VComponents.all; + +entity trb_net_clock_generator is + generic( + FREQUENCY_IN : real := 100.0; + FREQUENCY_OUT : real := 300.0; + CLOCK_MULT : integer range 1 to 32 := 3; + CLOCK_DIV : integer range 1 to 32 := 1; + CLKIN_DIVIDE_BY_2 : boolean := true; + CLKIN_PERIOD : real := 20.0 + ); + port( + RESET : in std_logic; + CLK_IN : in std_logic; + CLK_OUT : out std_logic; + LOCKED : out std_logic + ); + +end entity; + + +architecture trb_net_clock_generator_arch of trb_net_clock_generator is + signal FB_CLK, CLK0_Out, CLKFX : std_logic; +begin + U_DCM: DCM + generic map( + CLKFX_DIVIDE => CLOCK_DIV, -- Min 1 Max 32 + CLKFX_MULTIPLY => CLOCK_MULT, -- Min 2 Max 32 + CLKIN_PERIOD => CLKIN_PERIOD, + STARTUP_WAIT => FALSE, + CLKIN_DIVIDE_BY_2 => CLKIN_DIVIDE_BY_2 + ) + port map ( + CLKIN => CLK_IN, + CLKFB => FB_CLK, + DSSEN => '0', + PSINCDEC => '0', + PSEN => '0', + PSCLK => '0', + RST => RESET, + CLK0 => CLK0_Out, -- for feedback + CLKFX => CLKFX, + LOCKED => LOCKED + ); +U0_BUFG: BUFG + port map ( + I => CLK0_Out, + O => FB_CLK + ); +U1_BUFG: BUFG + port map ( + I => CLKFX, + O => CLK_OUT + ); +end architecture; \ No newline at end of file diff --git a/xilinx/trb_net_fifo_16bit_bram_dualport_arch.vhd b/xilinx/trb_net_fifo_16bit_bram_dualport_arch.vhd index 90cdcd3..2ad5337 100644 --- a/xilinx/trb_net_fifo_16bit_bram_dualport_arch.vhd +++ b/xilinx/trb_net_fifo_16bit_bram_dualport_arch.vhd @@ -1,36 +1,3 @@ ---Taken from Xilinx Application note 258 and modified to size 511x18 - - ---------------------------------------------------------------------------- --- -- --- Module : fifoctlr_ic_v2.vhd Last Update: 07/14/00 -- --- -- --- Description : FIFO controller top level. -- --- Implements a 511x36 FIFO with independent read/write -- --- clocks. -- --- -- --- The following VHDL code implements a 511x36 FIFO in a Virtex -- --- device. The inputs are a Read Clock and Read Enable, a Write Clock -- --- and Write Enable, Write Data, and a FIFO_gsr signal as an initial -- --- reset. The outputs are Read Data, Full, Empty, and the FIFOstatus -- --- outputs, which indicate roughly how full the FIFO is. -- --- -- --- Designer : Nick Camilleri -- --- -- --- Company : Xilinx, Inc. -- --- -- --- Disclaimer : THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY -- --- WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY -- --- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -- --- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. -- --- THEY ARE ONLY INTendED TO BE USED BY XILINX -- --- CUSTOMERS, AND WITHIN XILINX DEVICES. -- --- -- --- Copyright (c) 2000 Xilinx, Inc. -- --- All rights reserved -- --- -- ---------------------------------------------------------------------------- - library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; @@ -53,85 +20,15 @@ entity trb_net_fifo_16bit_bram_dualport is read_data_out: OUT std_logic_vector(17 downto 0); full_out: OUT std_logic; empty_out: OUT std_logic; - fifostatus_out: OUT std_logic_vector(3 downto 0); --counter for 1/16th of fifo - valid_read_out: OUT std_logic + fifostatus_out: OUT std_logic_vector(3 downto 0); + valid_read_out: OUT std_logic; + almost_empty_out:OUT std_logic; + almost_full_out :OUT std_logic ); end entity trb_net_fifo_16bit_bram_dualport; architecture trb_net_fifo_16bit_bram_dualport_arch of trb_net_fifo_16bit_bram_dualport is --- signal read_clock: std_logic; --- signal write_clock: std_logic; --- signal read_enable: std_logic; --- signal write_enable: std_logic; --- signal fifo_gsr: std_logic; --- signal read_data: std_logic_vector(17 downto 0); --- signal write_data: std_logic_vector(17 downto 0); --- signal full: std_logic; --- signal empty: std_logic; --- signal read_addr: std_logic_vector(9 downto 0); --- signal read_addrgray: std_logic_vector(8 downto 0); --- signal read_nextgray: std_logic_vector(8 downto 0); --- signal read_lastgray: std_logic_vector(8 downto 0); --- signal write_addr: std_logic_vector(9 downto 0); --- signal write_addrgray: std_logic_vector(8 downto 0); --- signal write_nextgray: std_logic_vector(8 downto 0); --- signal fifostatus: std_logic_vector(8 downto 0); --- signal read_allow: std_logic; --- signal write_allow: std_logic; --- signal empty_allow: std_logic; --- signal full_allow: std_logic; --- signal ecomp: std_logic_vector(8 downto 0); --- signal fcomp: std_logic_vector(8 downto 0); --- signal emuxcyo: std_logic_vector(8 downto 0); --- signal fmuxcyo: std_logic_vector(8 downto 0); --- signal emptyg: std_logic; --- signal fullg: std_logic; --- signal read_truegray: std_logic_vector(8 downto 0); --- signal rag_writesync: std_logic_vector(8 downto 0); --- signal ra_writesync: std_logic_vector(8 downto 0); --- signal write_addrr: std_logic_vector(8 downto 0); --- signal xorout: std_logic_vector(1 downto 0); --- signal gnd_bus: std_logic_vector(17 downto 0); --- signal gnd: std_logic; --- signal pwr: std_logic; --- --- component BUFG --- port ( --- I: IN std_logic; --- O: OUT std_logic); --- end component; --- --- component MUXCY_L --- port ( --- DI: IN std_logic; --- CI: IN std_logic; --- S: IN std_logic; --- LO: OUT std_logic); --- end component; --- attribute BOX_TYPE of MUXCY_L : component is "BLACK_BOX"; --- --- component RAMB16_S18_S18 --- port ( --- ADDRA: IN std_logic_vector(9 downto 0); --- ADDRB: IN std_logic_vector(9 downto 0); --- DIA: IN std_logic_vector(15 downto 0); --- DIB: IN std_logic_vector(15 downto 0); --- DIPA: IN std_logic_vector(1 downto 0); --- DIPB: IN std_logic_vector(1 downto 0); --- WEA: IN std_logic; --- WEB: IN std_logic; --- CLKA: IN std_logic; --- CLKB: IN std_logic; --- SSRA: IN std_logic; --- SSRB: IN std_logic; --- ENA: IN std_logic; --- ENB: IN std_logic; --- DOA: OUT std_logic_vector(15 downto 0); --- DOB: OUT std_logic_vector(15 downto 0); --- DOPA: OUT std_logic_vector(1 downto 0); --- DOPB: OUT std_logic_vector(1 downto 0)); --- end component; ---attribute BOX_TYPE of RAMB16_S18_S18 : component is "BLACK_BOX"; +attribute box_type: string; component xilinx_fifo_dualport_18x1k port ( din: IN std_logic_VECTOR(17 downto 0); @@ -145,18 +42,10 @@ architecture trb_net_fifo_16bit_bram_dualport_arch of trb_net_fifo_16bit_bram_du full: OUT std_logic; valid: OUT std_logic); end component; --- read_clock_in: IN std_logic; --- write_clock_in: IN std_logic; --- read_enable_in: IN std_logic; --- write_enable_in: IN std_logic; --- fifo_gsr_in: IN std_logic; --- write_data_in: IN std_logic_vector(17 downto 0); --- read_data_out: OUT std_logic_vector(17 downto 0); --- full_out: OUT std_logic; --- empty_out: OUT std_logic; --- fifostatus_out: OUT std_logic_vector(3 downto 0) --counter for 1/16th of fifo +attribute box_type of xilinx_fifo_dualport_18x1k : component is "black_box"; + BEGIN -FIFO_DP_BRAM : xilinx_fifo_dualport_18x1k + FIFO_DP_BRAM : xilinx_fifo_dualport_18x1k port map ( din => write_data_in, rd_clk => read_clock_in, @@ -170,405 +59,8 @@ FIFO_DP_BRAM : xilinx_fifo_dualport_18x1k valid => valid_read_out ); --- read_enable <= read_enable_in; --- write_enable <= write_enable_in; --- fifo_gsr <= fifo_gsr_in; --- write_data <= write_data_in; --- read_data_out <= read_data; --- full_out <= full; --- empty_out <= empty; --- fifostatus_out <= fifostatus(8 downto 5); --- gnd_bus <= "000000000000000000"; --- gnd <= '0'; --- pwr <= '1'; --- --- read_addr(9) <= '0'; --- write_addr(9) <= '0'; --- --- --- -------------------------------------------------------------------------- --- -- -- --- -- Global input clock buffers are instantianted for both the read_clock -- --- -- and the write_clock, to avoid skew problems. -- --- -- -- --- -------------------------------------------------------------------------- --- read_clock <= read_clock_in; --- write_clock <= write_clock_in; --- --gclk1: BUFG port map (I => read_clock_in, O => read_clock); --- --gclk2: BUFG port map (I => write_clock_in, O => write_clock); --- --- -------------------------------------------------------------------------- --- -- -- --- -- Block RAM instantiation for FIFO. Module is 512x18, of which one -- --- -- address location is sacrificed for the overall speed of the design. -- --- -- -- --- -------------------------------------------------------------------------- --- --- bram1: RAMB16_S18_S18 port map (ADDRA => read_addr, ADDRB => write_addr, --- DIA => gnd_bus(15 downto 0), DIPA => gnd_bus(17 downto 16), --- DIB => write_data(15 downto 0), DIPB => write_data(17 downto 16), --- WEA => gnd, WEB => pwr, CLKA => read_clock, CLKB => write_clock, --- SSRA => gnd, SSRB => gnd, ENA => read_allow, ENB => write_allow, --- DOA => read_data(15 downto 0), DOPA => read_data(17 downto 16) ); --- --- ---------------------------------------------------------------- --- -- -- --- -- Allow flags determine whether FIFO control logic can -- --- -- operate. If read_enable is driven high, and the FIFO is -- --- -- not Empty, then Reads are allowed. Similarly, if the -- --- -- write_enable signal is high, and the FIFO is not Full, -- --- -- then Writes are allowed. -- --- -- -- --- ---------------------------------------------------------------- --- --- read_allow <= (read_enable AND NOT empty); --- write_allow <= (write_enable AND NOT full); --- --- full_allow <= (full OR write_enable); --- empty_allow <= (empty OR read_enable); --- --- --------------------------------------------------------------- --- -- -- --- -- Empty flag is set on fifo_gsr (initial), or when gray -- --- -- code counters are equal, or when there is one word in -- --- -- the FIFO, and a Read operation is about to be performed. -- --- -- -- --- --------------------------------------------------------------- --- --- proc1: PROCESS (read_clock) --- BEGIN --- if rising_edge(read_clock) then --- IF (fifo_gsr = '1') THEN --- empty <= '1'; --- ELSIF (empty_allow = '1') THEN --- empty <= emptyg; --- end IF; --- end IF; --- end PROCESS proc1; --- --- --------------------------------------------------------------- --- -- -- --- -- Full flag is set on fifo_gsr (initial, but it is cleared -- --- -- on the first valid write_clock edge after fifo_gsr is -- --- -- de-asserted), or when Gray-code counters are one away -- --- -- from being equal (the Write Gray-code address is equal -- --- -- to the Last Read Gray-code address), or when the Next -- --- -- Write Gray-code address is equal to the Last Read Gray- -- --- -- code address, and a Write operation is about to be -- --- -- performed. -- --- -- -- --- --------------------------------------------------------------- --- --- proc2: PROCESS (write_clock) --- BEGIN --- if rising_edge(write_clock) then --- IF (fifo_gsr = '1') THEN --- full <= '1'; --- ELSIF (full_allow = '1') THEN --- full <= fullg; --- end IF; --- end IF; --- end PROCESS proc2; --- --- ---------------------------------------------------------------- --- -- -- --- -- Generation of Read address pointers. The primary one is -- --- -- binary (read_addr), and the Gray-code derivatives are -- --- -- generated via pipelining the binary-to-Gray-code result. -- --- -- The initial values are important, so they're in sequence. -- --- -- -- --- -- Grey-code addresses are used so that the registered -- --- -- Full and Empty flags are always clean, and never in an -- --- -- unknown state due to the asynchonous relationship of the -- --- -- Read and Write clocks. In the worst case scenario, Full -- --- -- and Empty would simply stay active one cycle longer, but -- --- -- it would not generate an error or give false values. -- --- -- -- --- ---------------------------------------------------------------- --- --- proc3: PROCESS (read_clock) --- BEGIN --- if rising_edge(read_clock) then --- IF (fifo_gsr = '1') THEN --- read_addr(8 downto 0) <= "000000000"; --- ELSIF (read_allow = '1') THEN --- read_addr(8 downto 0) <= read_addr(8 downto 0) + 1; --- end IF; --- end IF; --- end PROCESS proc3; --- --- proc4: PROCESS (read_clock) --- BEGIN --- if rising_edge(read_clock) then --- IF (fifo_gsr = '1') THEN --- read_nextgray <= "100000000"; --- ELSIF (read_allow = '1') THEN --- read_nextgray(8) <= read_addr(8); --- read_nextgray(7) <= read_addr(8) XOR read_addr(7); --- read_nextgray(6) <= read_addr(7) XOR read_addr(6); --- read_nextgray(5) <= read_addr(6) XOR read_addr(5); --- read_nextgray(4) <= read_addr(5) XOR read_addr(4); --- read_nextgray(3) <= read_addr(4) XOR read_addr(3); --- read_nextgray(2) <= read_addr(3) XOR read_addr(2); --- read_nextgray(1) <= read_addr(2) XOR read_addr(1); --- read_nextgray(0) <= read_addr(1) XOR read_addr(0); --- end IF; --- end IF; --- end PROCESS proc4; --- --- proc5: PROCESS (read_clock) --- BEGIN --- if rising_edge(read_clock) then --- IF (fifo_gsr = '1') THEN --- read_addrgray <= "100000001"; --- ELSIF (read_allow = '1') THEN --- read_addrgray <= read_nextgray; --- end IF; --- end IF; --- end PROCESS proc5; --- --- proc6: PROCESS (read_clock) --- BEGIN --- if rising_edge(read_clock) then --- IF (fifo_gsr = '1') THEN --- read_lastgray <= "100000011"; --- ELSIF (read_allow = '1') THEN --- read_lastgray <= read_addrgray; --- end IF; --- end IF; --- end PROCESS proc6; --- --- ---------------------------------------------------------------- --- -- -- --- -- Generation of Write address pointers. Identical copy of -- --- -- read pointer generation above, except for names. -- --- -- -- --- ---------------------------------------------------------------- --- --- proc7: PROCESS (write_clock) --- BEGIN --- if rising_edge(write_clock) then --- IF (fifo_gsr = '1') THEN --- write_addr(8 downto 0) <= "000000000"; --- ELSIF (write_allow = '1') THEN --- write_addr(8 downto 0) <= write_addr(8 downto 0) + 1; --- end IF; --- end IF; --- end PROCESS proc7; --- --- proc8: PROCESS (write_clock) --- BEGIN --- if rising_edge(write_clock) then --- IF (fifo_gsr = '1') THEN --- write_nextgray <= "100000000"; --- ELSIF (write_allow = '1') THEN --- write_nextgray(8) <= write_addr(8); --- write_nextgray(7) <= write_addr(8) XOR write_addr(7); --- write_nextgray(6) <= write_addr(7) XOR write_addr(6); --- write_nextgray(5) <= write_addr(6) XOR write_addr(5); --- write_nextgray(4) <= write_addr(5) XOR write_addr(4); --- write_nextgray(3) <= write_addr(4) XOR write_addr(3); --- write_nextgray(2) <= write_addr(3) XOR write_addr(2); --- write_nextgray(1) <= write_addr(2) XOR write_addr(1); --- write_nextgray(0) <= write_addr(1) XOR write_addr(0); --- end IF; --- end IF; --- end PROCESS proc8; --- --- proc9: PROCESS (write_clock) --- BEGIN --- if rising_edge(write_clock) then --- IF (fifo_gsr = '1') THEN --- write_addrgray <= "100000001"; --- ELSIF (write_allow = '1') THEN --- write_addrgray <= write_nextgray; --- end IF; --- end IF; --- end PROCESS proc9; --- --- ---------------------------------------------------------------- --- -- -- --- -- Alternative generation of FIFOstatus outputs. Used to -- --- -- determine how full FIFO is, based on how far the Write -- --- -- pointer is ahead of the Read pointer. read_truegray -- --- -- is synchronized to write_clock (rag_writesync), converted -- --- -- to binary (ra_writesync), and then subtracted from the -- --- -- pipelined write_addr (write_addrr) to find out how many -- --- -- words are in the FIFO (fifostatus). The top bits are -- --- -- then 1/2 full, 1/4 full, etc. (not mutually exclusive). -- --- -- fifostatus has a one-cycle latency on write_clock; or, -- --- -- one cycle after the write address is incremented on a -- --- -- write operation, fifostatus is updated with the new -- --- -- capacity information. There is a two-cycle latency on -- --- -- read operations. -- --- -- -- --- -- If read_clock is much faster than write_clock, it is -- --- -- possible that the fifostatus counter could drop several -- --- -- positions in one write_clock cycle, so the low-order bits -- --- -- of fifostatus are not as reliable. -- --- -- -- --- -- NOTE: If the fifostatus flags are not needed, then this -- --- -- section of logic can be trimmed, saving 20+ slices and -- --- -- improving the circuit performance. -- --- -- -- --- ---------------------------------------------------------------- --- gen_status0 : if USE_STATUS_FLAGS = 0 generate --- fifostatus <= (others => '0'); --- end generate; --- --- gen_status : if USE_STATUS_FLAGS = 1 generate --- --- proc10: PROCESS (read_clock, fifo_gsr) --- BEGIN --- IF (fifo_gsr = '1') THEN --- read_truegray <= "000000000"; --- ELSIF (read_clock'EVENT AND read_clock = '1') THEN --- read_truegray(8) <= read_addr(8); --- read_truegray(7) <= read_addr(8) XOR read_addr(7); --- read_truegray(6) <= read_addr(7) XOR read_addr(6); --- read_truegray(5) <= read_addr(6) XOR read_addr(5); --- read_truegray(4) <= read_addr(5) XOR read_addr(4); --- read_truegray(3) <= read_addr(4) XOR read_addr(3); --- read_truegray(2) <= read_addr(3) XOR read_addr(2); --- read_truegray(1) <= read_addr(2) XOR read_addr(1); --- read_truegray(0) <= read_addr(1) XOR read_addr(0); --- end IF; --- end PROCESS proc10; --- --- proc11: PROCESS (write_clock, fifo_gsr) --- BEGIN --- IF (fifo_gsr = '1') THEN --- rag_writesync <= "000000000"; --- ELSIF (write_clock'EVENT AND write_clock = '1') THEN --- rag_writesync <= read_truegray; --- end IF; --- end PROCESS proc11; --- --- xorout(0) <= (rag_writesync(8) XOR rag_writesync(7) XOR rag_writesync(6) XOR --- rag_writesync(5)); --- xorout(1) <= (rag_writesync(4) XOR rag_writesync(3) XOR rag_writesync(2) XOR --- rag_writesync(1)); --- --- ra_writesync(8) <= rag_writesync(8); --- ra_writesync(7) <= (rag_writesync(8) XOR rag_writesync(7)); --- ra_writesync(6) <= (rag_writesync(8) XOR rag_writesync(7) XOR rag_writesync(6)); --- ra_writesync(5) <= xorout(0); --- ra_writesync(4) <= (xorout(0) XOR rag_writesync(4)); --- ra_writesync(3) <= (xorout(0) XOR rag_writesync(4) XOR rag_writesync(3)); --- ra_writesync(2) <= (xorout(0) XOR rag_writesync(4) XOR rag_writesync(3) --- XOR rag_writesync(2)); --- ra_writesync(1) <= (xorout(0) XOR xorout(1)); --- ra_writesync(0) <= (xorout(0) XOR xorout(1) XOR rag_writesync(0)); --- --- proc12: PROCESS (write_clock, fifo_gsr) --- BEGIN --- IF (fifo_gsr = '1') THEN --- write_addrr <= "000000000"; --- ELSIF (write_clock'EVENT AND write_clock = '1') THEN --- write_addrr <= write_addr(8 downto 0); --- end IF; --- end PROCESS proc12; --- --- proc13: PROCESS (write_clock, fifo_gsr) --- BEGIN --- IF (fifo_gsr = '1') THEN --- fifostatus <= "000000000"; --- ELSIF (write_clock'EVENT AND write_clock = '1') THEN --- IF (full = '0') THEN --- fifostatus <= (write_addrr - ra_writesync); --- end IF; --- end IF; --- end PROCESS proc13; --- end generate; --- ---------------------------------------------------------------- --- -- -- --- -- The two conditions decoded with special carry logic are -- --- -- Empty and Full (gated versions). These are used to -- --- -- determine the next state of the Full/Empty flags. Carry -- --- -- logic is used for optimal speed. (The previous -- --- -- implementation of AlmostEmpty and AlmostFull have been -- --- -- wrapped into the corresponding carry chains for faster -- --- -- performance). -- --- -- -- --- -- When write_addrgray is equal to read_addrgray, the FIFO -- --- -- is Empty, and emptyg (combinatorial) is asserted. Or, -- --- -- when write_addrgray is equal to read_nextgray (1 word in -- --- -- the FIFO) then the FIFO potentially could be going Empty, -- --- -- so emptyg is asserted, and the Empty flip-flop enable is -- --- -- gated with empty_allow, which is conditioned with a valid -- --- -- read. -- --- -- -- --- -- Similarly, when read_lastgray is equal to write_addrgray, -- --- -- the FIFO is full (511 addresses). Or, when read_lastgray -- --- -- is equal to write_nextgray, then the FIFO potentially -- --- -- could be going Full, so fullg is asserted, and the Full -- --- -- flip-flop enable is gated with full_allow, which is -- --- -- conditioned with a valid write. -- --- -- -- --- -- Note: To have utilized the full address space (512) -- --- -- would have required extra logic to determine Full/Empty -- --- -- on equal addresses, and this would have slowed down the -- --- -- overall performance, which was the top priority. -- --- -- -- --- ---------------------------------------------------------------- --- --- ecomp(0) <= (NOT (write_addrgray(0) XOR read_addrgray(0)) AND empty) OR --- (NOT (write_addrgray(0) XOR read_nextgray(0)) AND NOT empty); --- ecomp(1) <= (NOT (write_addrgray(1) XOR read_addrgray(1)) AND empty) OR --- (NOT (write_addrgray(1) XOR read_nextgray(1)) AND NOT empty); --- ecomp(2) <= (NOT (write_addrgray(2) XOR read_addrgray(2)) AND empty) OR --- (NOT (write_addrgray(2) XOR read_nextgray(2)) AND NOT empty); --- ecomp(3) <= (NOT (write_addrgray(3) XOR read_addrgray(3)) AND empty) OR --- (NOT (write_addrgray(3) XOR read_nextgray(3)) AND NOT empty); --- ecomp(4) <= (NOT (write_addrgray(4) XOR read_addrgray(4)) AND empty) OR --- (NOT (write_addrgray(4) XOR read_nextgray(4)) AND NOT empty); --- ecomp(5) <= (NOT (write_addrgray(5) XOR read_addrgray(5)) AND empty) OR --- (NOT (write_addrgray(5) XOR read_nextgray(5)) AND NOT empty); --- ecomp(6) <= (NOT (write_addrgray(6) XOR read_addrgray(6)) AND empty) OR --- (NOT (write_addrgray(6) XOR read_nextgray(6)) AND NOT empty); --- ecomp(7) <= (NOT (write_addrgray(7) XOR read_addrgray(7)) AND empty) OR --- (NOT (write_addrgray(7) XOR read_nextgray(7)) AND NOT empty); --- ecomp(8) <= (NOT (write_addrgray(8) XOR read_addrgray(8)) AND empty) OR --- (NOT (write_addrgray(8) XOR read_nextgray(8)) AND NOT empty); --- --- emuxcy0: MUXCY_L port map (DI=>gnd,CI=>pwr, S=>ecomp(0),LO=>emuxcyo(0)); --- emuxcy1: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(0),S=>ecomp(1),LO=>emuxcyo(1)); --- emuxcy2: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(1),S=>ecomp(2),LO=>emuxcyo(2)); --- emuxcy3: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(2),S=>ecomp(3),LO=>emuxcyo(3)); --- emuxcy4: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(3),S=>ecomp(4),LO=>emuxcyo(4)); --- emuxcy5: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(4),S=>ecomp(5),LO=>emuxcyo(5)); --- emuxcy6: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(5),S=>ecomp(6),LO=>emuxcyo(6)); --- emuxcy7: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(6),S=>ecomp(7),LO=>emuxcyo(7)); --- emuxcy8: MUXCY_L port map (DI=>gnd,CI=>emuxcyo(7),S=>ecomp(8),LO=>emptyg); --- --- fcomp(0) <= (NOT (read_lastgray(0) XOR write_addrgray(0)) AND full) OR --- (NOT (read_lastgray(0) XOR write_nextgray(0)) AND NOT full); --- fcomp(1) <= (NOT (read_lastgray(1) XOR write_addrgray(1)) AND full) OR --- (NOT (read_lastgray(1) XOR write_nextgray(1)) AND NOT full); --- fcomp(2) <= (NOT (read_lastgray(2) XOR write_addrgray(2)) AND full) OR --- (NOT (read_lastgray(2) XOR write_nextgray(2)) AND NOT full); --- fcomp(3) <= (NOT (read_lastgray(3) XOR write_addrgray(3)) AND full) OR --- (NOT (read_lastgray(3) XOR write_nextgray(3)) AND NOT full); --- fcomp(4) <= (NOT (read_lastgray(4) XOR write_addrgray(4)) AND full) OR --- (NOT (read_lastgray(4) XOR write_nextgray(4)) AND NOT full); --- fcomp(5) <= (NOT (read_lastgray(5) XOR write_addrgray(5)) AND full) OR --- (NOT (read_lastgray(5) XOR write_nextgray(5)) AND NOT full); --- fcomp(6) <= (NOT (read_lastgray(6) XOR write_addrgray(6)) AND full) OR --- (NOT (read_lastgray(6) XOR write_nextgray(6)) AND NOT full); --- fcomp(7) <= (NOT (read_lastgray(7) XOR write_addrgray(7)) AND full) OR --- (NOT (read_lastgray(7) XOR write_nextgray(7)) AND NOT full); --- fcomp(8) <= (NOT (read_lastgray(8) XOR write_addrgray(8)) AND full) OR --- (NOT (read_lastgray(8) XOR write_nextgray(8)) AND NOT full); --- --- fmuxcy0: MUXCY_L port map (DI=>gnd,CI=>pwr, S=>fcomp(0),LO=>fmuxcyo(0)); --- fmuxcy1: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(0),S=>fcomp(1),LO=>fmuxcyo(1)); --- fmuxcy2: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(1),S=>fcomp(2),LO=>fmuxcyo(2)); --- fmuxcy3: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(2),S=>fcomp(3),LO=>fmuxcyo(3)); --- fmuxcy4: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(3),S=>fcomp(4),LO=>fmuxcyo(4)); --- fmuxcy5: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(4),S=>fcomp(5),LO=>fmuxcyo(5)); --- fmuxcy6: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(5),S=>fcomp(6),LO=>fmuxcyo(6)); --- fmuxcy7: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(6),S=>fcomp(7),LO=>fmuxcyo(7)); --- fmuxcy8: MUXCY_L port map (DI=>gnd,CI=>fmuxcyo(7),S=>fcomp(8),LO=>fullg); --- +almost_full_out <= '0'; +almost_empty_out <= '0'; +fifostatus_out <= (others => '0'); end architecture trb_net_fifo_16bit_bram_dualport_arch; diff --git a/xilinx/virtex4/xilinx_fifo_18x1k.vhd b/xilinx/virtex4/xilinx_fifo_18x1k.vhd new file mode 100644 index 0000000..a00c341 --- /dev/null +++ b/xilinx/virtex4/xilinx_fifo_18x1k.vhd @@ -0,0 +1,146 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- You must compile the wrapper file xilinx_fifo_18x1k.vhd when simulating +-- the core, xilinx_fifo_18x1k. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + +-- The synthesis directives "translate_off/translate_on" specified +-- below are supported by Xilinx, Mentor Graphics and Synplicity +-- synthesis tools. Ensure they are correct for your synthesis tool(s). + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +-- synthesis translate_off +Library XilinxCoreLib; +-- synthesis translate_on +ENTITY xilinx_fifo_18x1k IS + port ( + clk: IN std_logic; + din: IN std_logic_VECTOR(17 downto 0); + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic); +END xilinx_fifo_18x1k; + +ARCHITECTURE xilinx_fifo_18x1k_a OF xilinx_fifo_18x1k IS +-- synthesis translate_off +component wrapped_xilinx_fifo_18x1k + port ( + clk: IN std_logic; + din: IN std_logic_VECTOR(17 downto 0); + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic); +end component; + +-- Configuration specification + for all : wrapped_xilinx_fifo_18x1k use entity XilinxCoreLib.fifo_generator_v4_2(behavioral) + generic map( + c_has_int_clk => 0, + c_rd_freq => 1, + c_wr_response_latency => 1, + c_has_srst => 0, + c_has_rd_data_count => 0, + c_din_width => 18, + c_has_wr_data_count => 0, + c_full_flags_rst_val => 0, + c_implementation_type => 3, + c_family => "virtex4", + c_use_embedded_reg => 0, + c_has_wr_rst => 0, + c_wr_freq => 1, + c_use_dout_rst => 0, + c_underflow_low => 0, + c_has_meminit_file => 0, + c_has_overflow => 0, + c_preload_latency => 1, + c_dout_width => 18, + c_rd_depth => 1024, + c_default_value => "BlankString", + c_mif_file_name => "BlankString", + c_has_underflow => 0, + c_has_rd_rst => 0, + c_has_almost_full => 0, + c_has_rst => 1, + c_data_count_width => 10, + c_has_wr_ack => 0, + c_use_ecc => 0, + c_wr_ack_low => 0, + c_common_clock => 1, + c_rd_pntr_width => 10, + c_use_fwft_data_count => 0, + c_has_almost_empty => 0, + c_rd_data_count_width => 10, + c_enable_rlocs => 0, + c_wr_pntr_width => 10, + c_overflow_low => 0, + c_prog_empty_type => 0, + c_optimization_mode => 0, + c_wr_data_count_width => 10, + c_preload_regs => 0, + c_dout_rst_val => "0", + c_has_data_count => 0, + c_prog_full_thresh_negate_val => 1034, + c_wr_depth => 1024, + c_prog_empty_thresh_negate_val => 20, + c_prog_empty_thresh_assert_val => 19, + c_has_valid => 0, + c_init_wr_pntr_val => 0, + c_prog_full_thresh_assert_val => 1035, + c_use_fifo16_flags => 0, + c_has_backup => 0, + c_valid_low => 0, + c_prim_fifo_type => "1kx18", + c_count_type => 0, + c_prog_full_type => 0, + c_memory_type => 4); +-- synthesis translate_on +BEGIN +-- synthesis translate_off +U0 : wrapped_xilinx_fifo_18x1k + port map ( + clk => clk, + din => din, + rd_en => rd_en, + rst => rst, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full); +-- synthesis translate_on + +END xilinx_fifo_18x1k_a; + diff --git a/xilinx/virtex4/xilinx_fifo_dualport_18x1k.vhd b/xilinx/virtex4/xilinx_fifo_dualport_18x1k.vhd new file mode 100644 index 0000000..85c40e5 --- /dev/null +++ b/xilinx/virtex4/xilinx_fifo_dualport_18x1k.vhd @@ -0,0 +1,142 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- You must compile the wrapper file xilinx_fifo_dualport_18x1k.vhd when simulating +-- the core, xilinx_fifo_dualport_18x1k. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + +-- The synthesis directives "translate_off/translate_on" specified +-- below are supported by Xilinx, Mentor Graphics and Synplicity +-- synthesis tools. Ensure they are correct for your synthesis tool(s). + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +-- synthesis translate_off +Library XilinxCoreLib; +-- synthesis translate_on +ENTITY xilinx_fifo_dualport_18x1k IS + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + valid: OUT std_logic); +END xilinx_fifo_dualport_18x1k; + +ARCHITECTURE xilinx_fifo_dualport_18x1k_a OF xilinx_fifo_dualport_18x1k IS +-- synthesis translate_off +component wrapped_xilinx_fifo_dualport_18x1k + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + valid: OUT std_logic); +end component; + +-- Configuration specification + for all : wrapped_xilinx_fifo_dualport_18x1k use entity XilinxCoreLib.fifo_generator_v2_1(behavioral) + generic map( + c_wr_response_latency => 1, + c_has_rd_data_count => 0, + c_din_width => 18, + c_has_wr_data_count => 0, + c_implementation_type => 2, + c_family => "virtex2", + c_has_wr_rst => 0, + c_underflow_low => 0, + c_has_meminit_file => 0, + c_has_overflow => 0, + c_preload_latency => 1, + c_dout_width => 18, + c_rd_depth => 1024, + c_default_value => "BlankString", + c_mif_file_name => "BlankString", + c_has_underflow => 0, + c_has_rd_rst => 0, + c_has_almost_full => 0, + c_has_rst => 1, + c_data_count_width => 2, + c_has_wr_ack => 0, + c_wr_ack_low => 0, + c_common_clock => 0, + c_rd_pntr_width => 10, + c_has_almost_empty => 0, + c_rd_data_count_width => 2, + c_enable_rlocs => 0, + c_wr_pntr_width => 10, + c_overflow_low => 0, + c_prog_empty_type => 0, + c_optimization_mode => 0, + c_wr_data_count_width => 2, + c_preload_regs => 0, + c_dout_rst_val => "0", + c_has_data_count => 0, + c_prog_full_thresh_negate_val => 768, + c_wr_depth => 1024, + c_prog_empty_thresh_negate_val => 256, + c_prog_empty_thresh_assert_val => 256, + c_has_valid => 1, + c_init_wr_pntr_val => 0, + c_prog_full_thresh_assert_val => 768, + c_has_backup => 0, + c_valid_low => 0, + c_prim_fifo_type => 1024, + c_count_type => 0, + c_prog_full_type => 0, + c_memory_type => 1); +-- synthesis translate_on +BEGIN +-- synthesis translate_off +U0 : wrapped_xilinx_fifo_dualport_18x1k + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + valid => valid); +-- synthesis translate_on + +END xilinx_fifo_dualport_18x1k_a; + diff --git a/xilinx/virtex4/xilinx_fifo_dualport_18x1k.xco b/xilinx/virtex4/xilinx_fifo_dualport_18x1k.xco index f20d1df..0f62ad6 100644 --- a/xilinx/virtex4/xilinx_fifo_dualport_18x1k.xco +++ b/xilinx/virtex4/xilinx_fifo_dualport_18x1k.xco @@ -1,7 +1,7 @@ ############################################################## # # Xilinx Core Generator version J.40 -# Date: Mon Feb 25 10:17:29 2008 +# Date: Thu Jul 24 16:53:38 2008 # ############################################################## # @@ -41,14 +41,14 @@ CSET component_name=xilinx_fifo_dualport_18x1k CSET data_count=false CSET data_count_width=10 CSET dout_reset_value=0 -CSET empty_threshold_assert_value=19 -CSET empty_threshold_negate_value=20 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 CSET enable_ecc=false CSET enable_int_clk=false -CSET fifo_implementation=Independent_Clocks_Builtin_FIFO -CSET full_flags_reset_value=0 -CSET full_threshold_assert_value=1035 -CSET full_threshold_negate_value=1034 +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=1021 +CSET full_threshold_negate_value=1020 CSET input_data_width=18 CSET input_depth=1024 CSET output_data_width=18 @@ -58,7 +58,7 @@ CSET overflow_sense=Active_High CSET performance_options=Standard_FIFO CSET programmable_empty_type=No_Programmable_Empty_Threshold CSET programmable_full_type=No_Programmable_Full_Threshold -CSET read_clock_frequency=100 +CSET read_clock_frequency=1 CSET read_data_count=false CSET read_data_count_width=10 CSET reset_pin=true @@ -72,10 +72,10 @@ CSET valid_flag=true CSET valid_sense=Active_High CSET write_acknowledge_flag=false CSET write_acknowledge_sense=Active_High -CSET write_clock_frequency=100 +CSET write_clock_frequency=1 CSET write_data_count=false CSET write_data_count_width=10 # END Parameters GENERATE -# CRC: e1de2b03 +# CRC: 2635dae -- 2.43.0