From 75e66689d4f2854abc801e0ec32bbfe896e3ee0c Mon Sep 17 00:00:00 2001 From: Jeroen van Straten Date: Tue, 5 Jan 2021 17:26:05 +0100 Subject: [PATCH 1/9] Add write response channel to interconnect --- hardware/interconnect/BusWriteArbiter.vhd | 194 ++++++++++++-- hardware/interconnect/BusWriteArbiterVec.vhd | 250 +++++++++++++++--- hardware/interconnect/BusWriteBuffer.vhd | 57 +++- hardware/interconnect/Interconnect_pkg.vhd | 193 ++++++++++---- .../interconnect/test/BusChecking_pkg.vhd | 6 +- .../interconnect/test/BusProtocolChecker.vhd | 6 +- .../interconnect/test/BusWriteArbiter_tb.vhd | 100 ++++++- .../interconnect/test/BusWriteMasterMock.vhd | 10 +- .../interconnect/test/BusWriteSlaveMock.vhd | 20 +- 9 files changed, 707 insertions(+), 129 deletions(-) diff --git a/hardware/interconnect/BusWriteArbiter.vhd b/hardware/interconnect/BusWriteArbiter.vhd index 2588315d9..5ba07f51f 100644 --- a/hardware/interconnect/BusWriteArbiter.vhd +++ b/hardware/interconnect/BusWriteArbiter.vhd @@ -55,11 +55,17 @@ entity BusWriteArbiter is -- Whether a register slice should be inserted into the master request port MST_REQ_SLICE : boolean := true; + -- Whether a register slice should be inserted into the slave data ports + SLV_DAT_SLICES : boolean := true; + -- Whether a register slice should be inserted into the master data port MST_DAT_SLICE : boolean := true; - -- Whether a register slice should be inserted into the slave data ports - SLV_DAT_SLICES : boolean := true + -- Whether a register slice should be inserted into the master response port + MST_REP_SLICE : boolean := true; + + -- Whether a register slice should be inserted into the slave response ports + SLV_REP_SLICES : boolean := true ); port ( @@ -73,11 +79,15 @@ entity BusWriteArbiter is mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); mst_wdat_last : out std_logic; + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic; -- Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn @@ -86,176 +96,240 @@ entity BusWriteArbiter is bs00_wreq_ready : out std_logic; bs00_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs00_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs00_wreq_last : in std_logic := '0'; bs00_wdat_valid : in std_logic := '0'; - bs00_wdat_ready : out std_logic := '1'; + bs00_wdat_ready : out std_logic; bs00_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs00_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs00_wdat_last : in std_logic := 'U'; + bs00_wrep_valid : out std_logic; + bs00_wrep_ready : in std_logic := '1'; + bs00_wrep_ok : out std_logic; -- Slave port 1. bs01_wreq_valid : in std_logic := '0'; bs01_wreq_ready : out std_logic; bs01_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs01_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs01_wreq_last : in std_logic := '0'; bs01_wdat_valid : in std_logic := '0'; - bs01_wdat_ready : out std_logic := '1'; + bs01_wdat_ready : out std_logic; bs01_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs01_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs01_wdat_last : in std_logic := 'U'; + bs01_wrep_valid : out std_logic; + bs01_wrep_ready : in std_logic := '1'; + bs01_wrep_ok : out std_logic; -- Slave port 2. bs02_wreq_valid : in std_logic := '0'; bs02_wreq_ready : out std_logic; bs02_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs02_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs02_wreq_last : in std_logic := '0'; bs02_wdat_valid : in std_logic := '0'; - bs02_wdat_ready : out std_logic := '1'; + bs02_wdat_ready : out std_logic; bs02_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs02_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs02_wdat_last : in std_logic := 'U'; + bs02_wrep_valid : out std_logic; + bs02_wrep_ready : in std_logic := '1'; + bs02_wrep_ok : out std_logic; -- Slave port 3. bs03_wreq_valid : in std_logic := '0'; bs03_wreq_ready : out std_logic; bs03_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs03_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs03_wreq_last : in std_logic := '0'; bs03_wdat_valid : in std_logic := '0'; - bs03_wdat_ready : out std_logic := '1'; + bs03_wdat_ready : out std_logic; bs03_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs03_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs03_wdat_last : in std_logic := 'U'; + bs03_wrep_valid : out std_logic; + bs03_wrep_ready : in std_logic := '1'; + bs03_wrep_ok : out std_logic; -- Slave port 4. bs04_wreq_valid : in std_logic := '0'; bs04_wreq_ready : out std_logic; bs04_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs04_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs04_wreq_last : in std_logic := '0'; bs04_wdat_valid : in std_logic := '0'; - bs04_wdat_ready : out std_logic := '1'; + bs04_wdat_ready : out std_logic; bs04_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs04_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs04_wdat_last : in std_logic := 'U'; + bs04_wrep_valid : out std_logic; + bs04_wrep_ready : in std_logic := '1'; + bs04_wrep_ok : out std_logic; -- Slave port 5. bs05_wreq_valid : in std_logic := '0'; bs05_wreq_ready : out std_logic; bs05_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs05_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs05_wreq_last : in std_logic := '0'; bs05_wdat_valid : in std_logic := '0'; - bs05_wdat_ready : out std_logic := '1'; + bs05_wdat_ready : out std_logic; bs05_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs05_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs05_wdat_last : in std_logic := 'U'; + bs05_wrep_valid : out std_logic; + bs05_wrep_ready : in std_logic := '1'; + bs05_wrep_ok : out std_logic; -- Slave port 6. bs06_wreq_valid : in std_logic := '0'; bs06_wreq_ready : out std_logic; bs06_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs06_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs06_wreq_last : in std_logic := '0'; bs06_wdat_valid : in std_logic := '0'; - bs06_wdat_ready : out std_logic := '1'; + bs06_wdat_ready : out std_logic; bs06_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs06_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs06_wdat_last : in std_logic := 'U'; + bs06_wrep_valid : out std_logic; + bs06_wrep_ready : in std_logic := '1'; + bs06_wrep_ok : out std_logic; -- Slave port 7. bs07_wreq_valid : in std_logic := '0'; bs07_wreq_ready : out std_logic; bs07_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs07_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs07_wreq_last : in std_logic := '0'; bs07_wdat_valid : in std_logic := '0'; - bs07_wdat_ready : out std_logic := '1'; + bs07_wdat_ready : out std_logic; bs07_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs07_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs07_wdat_last : in std_logic := 'U'; + bs07_wrep_valid : out std_logic; + bs07_wrep_ready : in std_logic := '1'; + bs07_wrep_ok : out std_logic; -- Slave port 8. bs08_wreq_valid : in std_logic := '0'; bs08_wreq_ready : out std_logic; bs08_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs08_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs08_wreq_last : in std_logic := '0'; bs08_wdat_valid : in std_logic := '0'; - bs08_wdat_ready : out std_logic := '1'; + bs08_wdat_ready : out std_logic; bs08_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs08_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs08_wdat_last : in std_logic := 'U'; + bs08_wrep_valid : out std_logic; + bs08_wrep_ready : in std_logic := '1'; + bs08_wrep_ok : out std_logic; -- Slave port 9. bs09_wreq_valid : in std_logic := '0'; bs09_wreq_ready : out std_logic; bs09_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs09_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs09_wreq_last : in std_logic := '0'; bs09_wdat_valid : in std_logic := '0'; - bs09_wdat_ready : out std_logic := '1'; + bs09_wdat_ready : out std_logic; bs09_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs09_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs09_wdat_last : in std_logic := 'U'; + bs09_wrep_valid : out std_logic; + bs09_wrep_ready : in std_logic := '1'; + bs09_wrep_ok : out std_logic; -- Slave port 10. bs10_wreq_valid : in std_logic := '0'; bs10_wreq_ready : out std_logic; bs10_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs10_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs10_wreq_last : in std_logic := '0'; bs10_wdat_valid : in std_logic := '0'; - bs10_wdat_ready : out std_logic := '1'; + bs10_wdat_ready : out std_logic; bs10_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs10_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs10_wdat_last : in std_logic := 'U'; + bs10_wrep_valid : out std_logic; + bs10_wrep_ready : in std_logic := '1'; + bs10_wrep_ok : out std_logic; -- Slave port 11. bs11_wreq_valid : in std_logic := '0'; bs11_wreq_ready : out std_logic; bs11_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs11_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs11_wreq_last : in std_logic := '0'; bs11_wdat_valid : in std_logic := '0'; - bs11_wdat_ready : out std_logic := '1'; + bs11_wdat_ready : out std_logic; bs11_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs11_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs11_wdat_last : in std_logic := 'U'; + bs11_wrep_valid : out std_logic; + bs11_wrep_ready : in std_logic := '1'; + bs11_wrep_ok : out std_logic; -- Slave port 12. bs12_wreq_valid : in std_logic := '0'; bs12_wreq_ready : out std_logic; bs12_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs12_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs12_wreq_last : in std_logic := '0'; bs12_wdat_valid : in std_logic := '0'; - bs12_wdat_ready : out std_logic := '1'; + bs12_wdat_ready : out std_logic; bs12_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs12_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs12_wdat_last : in std_logic := 'U'; + bs12_wrep_valid : out std_logic; + bs12_wrep_ready : in std_logic := '1'; + bs12_wrep_ok : out std_logic; -- Slave port 13. bs13_wreq_valid : in std_logic := '0'; bs13_wreq_ready : out std_logic; bs13_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs13_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs13_wreq_last : in std_logic := '0'; bs13_wdat_valid : in std_logic := '0'; - bs13_wdat_ready : out std_logic := '1'; + bs13_wdat_ready : out std_logic; bs13_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs13_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs13_wdat_last : in std_logic := 'U'; + bs13_wrep_valid : out std_logic; + bs13_wrep_ready : in std_logic := '1'; + bs13_wrep_ok : out std_logic; -- Slave port 14. bs14_wreq_valid : in std_logic := '0'; bs14_wreq_ready : out std_logic; bs14_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs14_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs14_wreq_last : in std_logic := '0'; bs14_wdat_valid : in std_logic := '0'; - bs14_wdat_ready : out std_logic := '1'; + bs14_wdat_ready : out std_logic; bs14_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs14_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs14_wdat_last : in std_logic := 'U'; + bs14_wrep_valid : out std_logic; + bs14_wrep_ready : in std_logic := '1'; + bs14_wrep_ok : out std_logic; -- Slave port 15. bs15_wreq_valid : in std_logic := '0'; bs15_wreq_ready : out std_logic; bs15_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs15_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs15_wreq_last : in std_logic := '0'; bs15_wdat_valid : in std_logic := '0'; - bs15_wdat_ready : out std_logic := '1'; + bs15_wdat_ready : out std_logic; bs15_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs15_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); - bs15_wdat_last : in std_logic := 'U' + bs15_wdat_last : in std_logic := 'U'; + bs15_wrep_valid : out std_logic; + bs15_wrep_ready : in std_logic := '1'; + bs15_wrep_ok : out std_logic ); end BusWriteArbiter; @@ -266,11 +340,15 @@ architecture Behavioral of BusWriteArbiter is signal bsv_wreq_ready : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); signal bsv_wreq_addr : std_logic_vector(NUM_SLAVE_PORTS*BUS_ADDR_WIDTH-1 downto 0); signal bsv_wreq_len : std_logic_vector(NUM_SLAVE_PORTS*BUS_LEN_WIDTH-1 downto 0); + signal bsv_wreq_last : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); signal bsv_wdat_valid : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); signal bsv_wdat_ready : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); signal bsv_wdat_data : std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH-1 downto 0); signal bsv_wdat_strobe : std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH/8-1 downto 0); signal bsv_wdat_last : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + signal bsv_wrep_valid : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + signal bsv_wrep_ready : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + signal bsv_wrep_ok : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); begin -- Connect bus slave 0 to internal signal. @@ -280,11 +358,15 @@ begin bs00_wreq_ready <= bsv_wreq_ready( 0); bsv_wreq_addr ( 1*BUS_ADDR_WIDTH-1 downto 0*BUS_ADDR_WIDTH) <= bs00_wreq_addr; bsv_wreq_len ( 1*BUS_LEN_WIDTH-1 downto 0*BUS_LEN_WIDTH) <= bs00_wreq_len; + bsv_wreq_last ( 0) <= bs00_wreq_last; bsv_wdat_valid ( 0) <= bs00_wdat_valid; bs00_wdat_ready <= bsv_wdat_ready( 0); bsv_wdat_data ( 1*BUS_DATA_WIDTH-1 downto 0*BUS_DATA_WIDTH) <= bs00_wdat_data; bsv_wdat_strobe( 1*BUS_DATA_WIDTH/8-1 downto 0*BUS_DATA_WIDTH/8) <= bs00_wdat_strobe; bsv_wdat_last ( 0) <= bs00_wdat_last; + bs00_wrep_valid <= bsv_wrep_valid( 0); + bsv_wrep_ready ( 0) <= bs00_wrep_ready; + bs00_wrep_ok <= bsv_wrep_ok( 0); end generate; -- Connect bus slave 1 to internal signal. @@ -294,11 +376,15 @@ begin bs01_wreq_ready <= bsv_wreq_ready( 1); bsv_wreq_addr ( 2*BUS_ADDR_WIDTH-1 downto 1*BUS_ADDR_WIDTH) <= bs01_wreq_addr; bsv_wreq_len ( 2*BUS_LEN_WIDTH-1 downto 1*BUS_LEN_WIDTH) <= bs01_wreq_len; + bsv_wreq_last ( 1) <= bs01_wreq_last; bsv_wdat_valid ( 1) <= bs01_wdat_valid; bs01_wdat_ready <= bsv_wdat_ready( 1); bsv_wdat_data ( 2*BUS_DATA_WIDTH-1 downto 1*BUS_DATA_WIDTH) <= bs01_wdat_data; bsv_wdat_strobe( 2*BUS_DATA_WIDTH/8-1 downto 1*BUS_DATA_WIDTH/8) <= bs01_wdat_strobe; bsv_wdat_last ( 1) <= bs01_wdat_last; + bs01_wrep_valid <= bsv_wrep_valid( 1); + bsv_wrep_ready ( 1) <= bs01_wrep_ready; + bs01_wrep_ok <= bsv_wrep_ok( 1); end generate; -- Connect bus slave 2 to internal signal. @@ -308,11 +394,15 @@ begin bs02_wreq_ready <= bsv_wreq_ready( 2); bsv_wreq_addr ( 3*BUS_ADDR_WIDTH-1 downto 2*BUS_ADDR_WIDTH) <= bs02_wreq_addr; bsv_wreq_len ( 3*BUS_LEN_WIDTH-1 downto 2*BUS_LEN_WIDTH) <= bs02_wreq_len; + bsv_wreq_last ( 2) <= bs02_wreq_last; bsv_wdat_valid ( 2) <= bs02_wdat_valid; bs02_wdat_ready <= bsv_wdat_ready( 2); bsv_wdat_data ( 3*BUS_DATA_WIDTH-1 downto 2*BUS_DATA_WIDTH) <= bs02_wdat_data; bsv_wdat_strobe( 3*BUS_DATA_WIDTH/8-1 downto 2*BUS_DATA_WIDTH/8) <= bs02_wdat_strobe; bsv_wdat_last ( 2) <= bs02_wdat_last; + bs02_wrep_valid <= bsv_wrep_valid( 2); + bsv_wrep_ready ( 2) <= bs02_wrep_ready; + bs02_wrep_ok <= bsv_wrep_ok( 2); end generate; -- Connect bus slave 3 to internal signal. @@ -322,11 +412,15 @@ begin bs03_wreq_ready <= bsv_wreq_ready( 3); bsv_wreq_addr ( 4*BUS_ADDR_WIDTH-1 downto 3*BUS_ADDR_WIDTH) <= bs03_wreq_addr; bsv_wreq_len ( 4*BUS_LEN_WIDTH-1 downto 3*BUS_LEN_WIDTH) <= bs03_wreq_len; + bsv_wreq_last ( 3) <= bs03_wreq_last; bsv_wdat_valid ( 3) <= bs03_wdat_valid; bs03_wdat_ready <= bsv_wdat_ready( 3); bsv_wdat_data ( 4*BUS_DATA_WIDTH-1 downto 3*BUS_DATA_WIDTH) <= bs03_wdat_data; bsv_wdat_strobe( 4*BUS_DATA_WIDTH/8-1 downto 3*BUS_DATA_WIDTH/8) <= bs03_wdat_strobe; bsv_wdat_last ( 3) <= bs03_wdat_last; + bs03_wrep_valid <= bsv_wrep_valid( 3); + bsv_wrep_ready ( 3) <= bs03_wrep_ready; + bs03_wrep_ok <= bsv_wrep_ok( 3); end generate; -- Connect bus slave 4 to internal signal. @@ -336,11 +430,15 @@ begin bs04_wreq_ready <= bsv_wreq_ready( 4); bsv_wreq_addr ( 5*BUS_ADDR_WIDTH-1 downto 4*BUS_ADDR_WIDTH) <= bs04_wreq_addr; bsv_wreq_len ( 5*BUS_LEN_WIDTH-1 downto 4*BUS_LEN_WIDTH) <= bs04_wreq_len; + bsv_wreq_last ( 4) <= bs04_wreq_last; bsv_wdat_valid ( 4) <= bs04_wdat_valid; bs04_wdat_ready <= bsv_wdat_ready( 4); bsv_wdat_data ( 5*BUS_DATA_WIDTH-1 downto 4*BUS_DATA_WIDTH) <= bs04_wdat_data; bsv_wdat_strobe( 5*BUS_DATA_WIDTH/8-1 downto 4*BUS_DATA_WIDTH/8) <= bs04_wdat_strobe; bsv_wdat_last ( 4) <= bs04_wdat_last; + bs04_wrep_valid <= bsv_wrep_valid( 4); + bsv_wrep_ready ( 4) <= bs04_wrep_ready; + bs04_wrep_ok <= bsv_wrep_ok( 4); end generate; -- Connect bus slave 5 to internal signal. @@ -350,11 +448,15 @@ begin bs05_wreq_ready <= bsv_wreq_ready( 5); bsv_wreq_addr ( 6*BUS_ADDR_WIDTH-1 downto 5*BUS_ADDR_WIDTH) <= bs05_wreq_addr; bsv_wreq_len ( 6*BUS_LEN_WIDTH-1 downto 5*BUS_LEN_WIDTH) <= bs05_wreq_len; + bsv_wreq_last ( 5) <= bs05_wreq_last; bsv_wdat_valid ( 5) <= bs05_wdat_valid; bs05_wdat_ready <= bsv_wdat_ready( 5); bsv_wdat_data ( 6*BUS_DATA_WIDTH-1 downto 5*BUS_DATA_WIDTH) <= bs05_wdat_data; bsv_wdat_strobe( 6*BUS_DATA_WIDTH/8-1 downto 5*BUS_DATA_WIDTH/8) <= bs05_wdat_strobe; bsv_wdat_last ( 5) <= bs05_wdat_last; + bs05_wrep_valid <= bsv_wrep_valid( 5); + bsv_wrep_ready ( 5) <= bs05_wrep_ready; + bs05_wrep_ok <= bsv_wrep_ok( 5); end generate; -- Connect bus slave 6 to internal signal. @@ -364,11 +466,15 @@ begin bs06_wreq_ready <= bsv_wreq_ready( 6); bsv_wreq_addr ( 7*BUS_ADDR_WIDTH-1 downto 6*BUS_ADDR_WIDTH) <= bs06_wreq_addr; bsv_wreq_len ( 7*BUS_LEN_WIDTH-1 downto 6*BUS_LEN_WIDTH) <= bs06_wreq_len; + bsv_wreq_last ( 6) <= bs06_wreq_last; bsv_wdat_valid ( 6) <= bs06_wdat_valid; bs06_wdat_ready <= bsv_wdat_ready( 6); bsv_wdat_data ( 7*BUS_DATA_WIDTH-1 downto 6*BUS_DATA_WIDTH) <= bs06_wdat_data; bsv_wdat_strobe( 7*BUS_DATA_WIDTH/8-1 downto 6*BUS_DATA_WIDTH/8) <= bs06_wdat_strobe; bsv_wdat_last ( 6) <= bs06_wdat_last; + bs06_wrep_valid <= bsv_wrep_valid( 6); + bsv_wrep_ready ( 6) <= bs06_wrep_ready; + bs06_wrep_ok <= bsv_wrep_ok( 6); end generate; -- Connect bus slave 7 to internal signal. @@ -378,11 +484,15 @@ begin bs07_wreq_ready <= bsv_wreq_ready( 7); bsv_wreq_addr ( 8*BUS_ADDR_WIDTH-1 downto 7*BUS_ADDR_WIDTH) <= bs07_wreq_addr; bsv_wreq_len ( 8*BUS_LEN_WIDTH-1 downto 7*BUS_LEN_WIDTH) <= bs07_wreq_len; + bsv_wreq_last ( 7) <= bs07_wreq_last; bsv_wdat_valid ( 7) <= bs07_wdat_valid; bs07_wdat_ready <= bsv_wdat_ready( 7); bsv_wdat_data ( 8*BUS_DATA_WIDTH-1 downto 7*BUS_DATA_WIDTH) <= bs07_wdat_data; bsv_wdat_strobe( 8*BUS_DATA_WIDTH/8-1 downto 7*BUS_DATA_WIDTH/8) <= bs07_wdat_strobe; bsv_wdat_last ( 7) <= bs07_wdat_last; + bs07_wrep_valid <= bsv_wrep_valid( 7); + bsv_wrep_ready ( 7) <= bs07_wrep_ready; + bs07_wrep_ok <= bsv_wrep_ok( 7); end generate; -- Connect bus slave 8 to internal signal. @@ -392,11 +502,15 @@ begin bs08_wreq_ready <= bsv_wreq_ready( 8); bsv_wreq_addr ( 9*BUS_ADDR_WIDTH-1 downto 8*BUS_ADDR_WIDTH) <= bs08_wreq_addr; bsv_wreq_len ( 9*BUS_LEN_WIDTH-1 downto 8*BUS_LEN_WIDTH) <= bs08_wreq_len; + bsv_wreq_last ( 8) <= bs08_wreq_last; bsv_wdat_valid ( 8) <= bs08_wdat_valid; bs08_wdat_ready <= bsv_wdat_ready( 8); bsv_wdat_data ( 9*BUS_DATA_WIDTH-1 downto 8*BUS_DATA_WIDTH) <= bs08_wdat_data; bsv_wdat_strobe( 9*BUS_DATA_WIDTH/8-1 downto 8*BUS_DATA_WIDTH/8) <= bs08_wdat_strobe; bsv_wdat_last ( 8) <= bs08_wdat_last; + bs08_wrep_valid <= bsv_wrep_valid( 8); + bsv_wrep_ready ( 8) <= bs08_wrep_ready; + bs08_wrep_ok <= bsv_wrep_ok( 8); end generate; -- Connect bus slave 9 to internal signal. @@ -406,11 +520,15 @@ begin bs09_wreq_ready <= bsv_wreq_ready( 9); bsv_wreq_addr (10*BUS_ADDR_WIDTH-1 downto 9*BUS_ADDR_WIDTH) <= bs09_wreq_addr; bsv_wreq_len (10*BUS_LEN_WIDTH-1 downto 9*BUS_LEN_WIDTH) <= bs09_wreq_len; + bsv_wreq_last ( 9) <= bs09_wreq_last; bsv_wdat_valid ( 9) <= bs09_wdat_valid; bs09_wdat_ready <= bsv_wdat_ready( 9); bsv_wdat_data (10*BUS_DATA_WIDTH-1 downto 9*BUS_DATA_WIDTH) <= bs09_wdat_data; bsv_wdat_strobe(10*BUS_DATA_WIDTH/8-1 downto 9*BUS_DATA_WIDTH/8) <= bs09_wdat_strobe; bsv_wdat_last ( 9) <= bs09_wdat_last; + bs09_wrep_valid <= bsv_wrep_valid( 9); + bsv_wrep_ready ( 9) <= bs09_wrep_ready; + bs09_wrep_ok <= bsv_wrep_ok( 9); end generate; -- Connect bus slave 10 to internal signal. @@ -420,11 +538,15 @@ begin bs10_wreq_ready <= bsv_wreq_ready(10); bsv_wreq_addr (11*BUS_ADDR_WIDTH-1 downto 10*BUS_ADDR_WIDTH) <= bs10_wreq_addr; bsv_wreq_len (11*BUS_LEN_WIDTH-1 downto 10*BUS_LEN_WIDTH) <= bs10_wreq_len; + bsv_wreq_last (10) <= bs10_wreq_last; bsv_wdat_valid (10) <= bs10_wdat_valid; bs10_wdat_ready <= bsv_wdat_ready(10); bsv_wdat_data (11*BUS_DATA_WIDTH-1 downto 10*BUS_DATA_WIDTH) <= bs10_wdat_data; bsv_wdat_strobe(11*BUS_DATA_WIDTH/8-1 downto 10*BUS_DATA_WIDTH/8) <= bs10_wdat_strobe; bsv_wdat_last (10) <= bs10_wdat_last; + bs10_wrep_valid <= bsv_wrep_valid(10); + bsv_wrep_ready (10) <= bs10_wrep_ready; + bs10_wrep_ok <= bsv_wrep_ok(10); end generate; -- Connect bus slave 11 to internal signal. @@ -434,11 +556,15 @@ begin bs11_wreq_ready <= bsv_wreq_ready(11); bsv_wreq_addr (12*BUS_ADDR_WIDTH-1 downto 11*BUS_ADDR_WIDTH) <= bs11_wreq_addr; bsv_wreq_len (12*BUS_LEN_WIDTH-1 downto 11*BUS_LEN_WIDTH) <= bs11_wreq_len; + bsv_wreq_last (11) <= bs11_wreq_last; bsv_wdat_valid (11) <= bs11_wdat_valid; bs11_wdat_ready <= bsv_wdat_ready(11); bsv_wdat_data (12*BUS_DATA_WIDTH-1 downto 11*BUS_DATA_WIDTH) <= bs11_wdat_data; bsv_wdat_strobe(12*BUS_DATA_WIDTH/8-1 downto 11*BUS_DATA_WIDTH/8) <= bs11_wdat_strobe; bsv_wdat_last (11) <= bs11_wdat_last; + bs11_wrep_valid <= bsv_wrep_valid(11); + bsv_wrep_ready (11) <= bs11_wrep_ready; + bs11_wrep_ok <= bsv_wrep_ok(11); end generate; -- Connect bus slave 12 to internal signal. @@ -448,11 +574,15 @@ begin bs12_wreq_ready <= bsv_wreq_ready(12); bsv_wreq_addr (13*BUS_ADDR_WIDTH-1 downto 12*BUS_ADDR_WIDTH) <= bs12_wreq_addr; bsv_wreq_len (13*BUS_LEN_WIDTH-1 downto 12*BUS_LEN_WIDTH) <= bs12_wreq_len; + bsv_wreq_last (12) <= bs12_wreq_last; bsv_wdat_valid (12) <= bs12_wdat_valid; bs12_wdat_ready <= bsv_wdat_ready(12); bsv_wdat_data (13*BUS_DATA_WIDTH-1 downto 12*BUS_DATA_WIDTH) <= bs12_wdat_data; bsv_wdat_strobe(13*BUS_DATA_WIDTH/8-1 downto 12*BUS_DATA_WIDTH/8) <= bs12_wdat_strobe; bsv_wdat_last (12) <= bs12_wdat_last; + bs12_wrep_valid <= bsv_wrep_valid(12); + bsv_wrep_ready (12) <= bs12_wrep_ready; + bs12_wrep_ok <= bsv_wrep_ok(12); end generate; -- Connect bus slave 13 to internal signal. @@ -462,11 +592,15 @@ begin bs13_wreq_ready <= bsv_wreq_ready(13); bsv_wreq_addr (14*BUS_ADDR_WIDTH-1 downto 13*BUS_ADDR_WIDTH) <= bs13_wreq_addr; bsv_wreq_len (14*BUS_LEN_WIDTH-1 downto 13*BUS_LEN_WIDTH) <= bs13_wreq_len; + bsv_wreq_last (13) <= bs13_wreq_last; bsv_wdat_valid (13) <= bs13_wdat_valid; bs13_wdat_ready <= bsv_wdat_ready(13); bsv_wdat_data (14*BUS_DATA_WIDTH-1 downto 13*BUS_DATA_WIDTH) <= bs13_wdat_data; bsv_wdat_strobe(14*BUS_DATA_WIDTH/8-1 downto 13*BUS_DATA_WIDTH/8) <= bs13_wdat_strobe; bsv_wdat_last (13) <= bs13_wdat_last; + bs13_wrep_valid <= bsv_wrep_valid(13); + bsv_wrep_ready (13) <= bs13_wrep_ready; + bs13_wrep_ok <= bsv_wrep_ok(13); end generate; -- Connect bus slave 14 to internal signal. @@ -476,11 +610,15 @@ begin bs14_wreq_ready <= bsv_wreq_ready(14); bsv_wreq_addr (15*BUS_ADDR_WIDTH-1 downto 14*BUS_ADDR_WIDTH) <= bs14_wreq_addr; bsv_wreq_len (15*BUS_LEN_WIDTH-1 downto 14*BUS_LEN_WIDTH) <= bs14_wreq_len; + bsv_wreq_last (14) <= bs14_wreq_last; bsv_wdat_valid (14) <= bs14_wdat_valid; bs14_wdat_ready <= bsv_wdat_ready(14); bsv_wdat_data (15*BUS_DATA_WIDTH-1 downto 14*BUS_DATA_WIDTH) <= bs14_wdat_data; bsv_wdat_strobe(15*BUS_DATA_WIDTH/8-1 downto 14*BUS_DATA_WIDTH/8) <= bs14_wdat_strobe; bsv_wdat_last (14) <= bs14_wdat_last; + bs14_wrep_valid <= bsv_wrep_valid(14); + bsv_wrep_ready (14) <= bs14_wrep_ready; + bs14_wrep_ok <= bsv_wrep_ok(14); end generate; -- Connect bus slave 15 to internal signal. @@ -490,11 +628,15 @@ begin bs15_wreq_ready <= bsv_wreq_ready(15); bsv_wreq_addr (16*BUS_ADDR_WIDTH-1 downto 15*BUS_ADDR_WIDTH) <= bs15_wreq_addr; bsv_wreq_len (16*BUS_LEN_WIDTH-1 downto 15*BUS_LEN_WIDTH) <= bs15_wreq_len; + bsv_wreq_last (15) <= bs15_wreq_last; bsv_wdat_valid (15) <= bs15_wdat_valid; bs15_wdat_ready <= bsv_wdat_ready(15); bsv_wdat_data (16*BUS_DATA_WIDTH-1 downto 15*BUS_DATA_WIDTH) <= bs15_wdat_data; bsv_wdat_strobe(16*BUS_DATA_WIDTH/8-1 downto 15*BUS_DATA_WIDTH/8) <= bs15_wdat_strobe; bsv_wdat_last (15) <= bs15_wdat_last; + bs15_wrep_valid <= bsv_wrep_valid(15); + bsv_wrep_ready (15) <= bs15_wrep_ready; + bs15_wrep_ok <= bsv_wrep_ok(15); end generate; -- Instantiate the vectorized version @@ -509,8 +651,10 @@ begin RAM_CONFIG => RAM_CONFIG, SLV_REQ_SLICES => SLV_REQ_SLICES, MST_REQ_SLICE => MST_REQ_SLICE, + SLV_DAT_SLICES => SLV_DAT_SLICES, MST_DAT_SLICE => MST_DAT_SLICE, - SLV_DAT_SLICES => SLV_DAT_SLICES + MST_REP_SLICE => MST_REP_SLICE, + SLV_REP_SLICES => SLV_REP_SLICES ) port map ( bcd_clk => bcd_clk, @@ -520,21 +664,29 @@ begin mst_wreq_ready => mst_wreq_ready, mst_wreq_addr => mst_wreq_addr, mst_wreq_len => mst_wreq_len, + mst_wreq_last => mst_wreq_last, mst_wdat_valid => mst_wdat_valid, mst_wdat_ready => mst_wdat_ready, mst_wdat_data => mst_wdat_data, mst_wdat_strobe => mst_wdat_strobe, mst_wdat_last => mst_wdat_last, + mst_wrep_valid => mst_wrep_valid, + mst_wrep_ready => mst_wrep_ready, + mst_wrep_ok => mst_wrep_ok, bsv_wreq_valid => bsv_wreq_valid, bsv_wreq_ready => bsv_wreq_ready, bsv_wreq_addr => bsv_wreq_addr, bsv_wreq_len => bsv_wreq_len, + bsv_wreq_last => bsv_wreq_last, bsv_wdat_valid => bsv_wdat_valid, bsv_wdat_ready => bsv_wdat_ready, bsv_wdat_data => bsv_wdat_data, bsv_wdat_strobe => bsv_wdat_strobe, - bsv_wdat_last => bsv_wdat_last + bsv_wdat_last => bsv_wdat_last, + bsv_wrep_valid => bsv_wrep_valid, + bsv_wrep_ready => bsv_wrep_ready, + bsv_wrep_ok => bsv_wrep_ok ); end Behavioral; diff --git a/hardware/interconnect/BusWriteArbiterVec.vhd b/hardware/interconnect/BusWriteArbiterVec.vhd index 94220a08d..bd226ee20 100644 --- a/hardware/interconnect/BusWriteArbiterVec.vhd +++ b/hardware/interconnect/BusWriteArbiterVec.vhd @@ -57,11 +57,17 @@ entity BusWriteArbiterVec is -- Whether a register slice should be inserted into the master request port MST_REQ_SLICE : boolean := true; + -- Whether a register slice should be inserted into the slave data ports + SLV_DAT_SLICES : boolean := false; + -- Whether a register slice should be inserted into the master data port - MST_DAT_SLICE : boolean := false; + MST_DAT_SLICE : boolean := true; - -- Whether a register slice should be inserted into the slave data ports - SLV_DAT_SLICES : boolean := true + -- Whether a register slice should be inserted into the master response port + MST_REP_SLICE : boolean := false; + + -- Whether a register slice should be inserted into the slave response ports + SLV_REP_SLICES : boolean := true ); port ( @@ -76,22 +82,30 @@ entity BusWriteArbiterVec is bsv_wreq_ready : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wreq_addr : in std_logic_vector(NUM_SLAVE_PORTS*BUS_ADDR_WIDTH-1 downto 0); bsv_wreq_len : in std_logic_vector(NUM_SLAVE_PORTS*BUS_LEN_WIDTH-1 downto 0); + bsv_wreq_last : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_valid : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_ready : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_data : in std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH-1 downto 0); bsv_wdat_strobe : in std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH/8-1 downto 0); bsv_wdat_last : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + bsv_wrep_valid : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + bsv_wrep_ready : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + bsv_wrep_ok : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); -- Master port. mst_wreq_valid : out std_logic; mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - mst_wdat_last : out std_logic + mst_wdat_last : out std_logic; + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic ); end BusWriteArbiterVec; @@ -125,47 +139,67 @@ architecture Behavioral of BusWriteArbiterVec is signal arbo_sData : std_logic_vector(BQI(BQI'high)-1 downto 0); -- Bus data channel serialization indices. - constant BPI : nat_array := cumulative(( + constant BDI : nat_array := cumulative(( 2 => BUS_DATA_WIDTH/8, 1 => BUS_DATA_WIDTH, 0 => 1 )); - signal mwdati_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); - signal mwdato_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); + signal mwdati_sData : std_logic_vector(BDI(BDI'high)-1 downto 0); + signal mwdato_sData : std_logic_vector(BDI(BDI'high)-1 downto 0); + + -- Bus response channel serialization indices. + constant BPI : nat_array := cumulative(( + 0 => 1 + )); + + signal mwrepi_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); + signal mwrepo_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); -- Copy of the bus slave signals in the entity as an array. signal bs_wreq_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bs_wreq_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bs_wreq_addr : bus_addr_array(0 to NUM_SLAVE_PORTS-1); signal bs_wreq_len : bus_len_array(0 to NUM_SLAVE_PORTS-1); + signal bs_wreq_last : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bs_wdat_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bs_wdat_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bs_wdat_data : bus_data_array(0 to NUM_SLAVE_PORTS-1); signal bs_wdat_strobe : bus_strobe_array(0 to NUM_SLAVE_PORTS-1); signal bs_wdat_last : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bs_wrep_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bs_wrep_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bs_wrep_ok : std_logic_vector(0 to NUM_SLAVE_PORTS-1); -- Register-sliced bus slave signals. signal bss_wreq_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bss_wreq_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bss_wreq_addr : bus_addr_array(0 to NUM_SLAVE_PORTS-1); signal bss_wreq_len : bus_len_array(0 to NUM_SLAVE_PORTS-1); + signal bss_wreq_last : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bss_wdat_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bss_wdat_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); signal bss_wdat_data : bus_data_array(0 to NUM_SLAVE_PORTS-1); signal bss_wdat_strobe : bus_strobe_array(0 to NUM_SLAVE_PORTS-1); signal bss_wdat_last : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bss_wrep_valid : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bss_wrep_ready : std_logic_vector(0 to NUM_SLAVE_PORTS-1); + signal bss_wrep_ok : std_logic_vector(0 to NUM_SLAVE_PORTS-1); -- Register-sliced bus master signals. signal bms_wreq_valid : std_logic; signal bms_wreq_ready : std_logic; signal bms_wreq_addr : bus_addr_type; signal bms_wreq_len : bus_len_type; + signal bms_wreq_last : std_logic; signal bms_wdat_valid : std_logic; signal bms_wdat_ready : std_logic; signal bms_wdat_data : bus_data_type; signal bms_wdat_strobe : bus_strobe_type; signal bms_wdat_last : std_logic; + signal bms_wrep_valid : std_logic; + signal bms_wrep_ready : std_logic; + signal bms_wrep_ok : std_logic; -- Serialized arbiter input signals. signal arb_in_valid : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); @@ -176,24 +210,39 @@ architecture Behavioral of BusWriteArbiterVec is signal arb_out_valid : std_logic; signal arb_out_ready : std_logic; - -- Index stream stage A (between sync and buffer). + -- Index stream stage A (between sync and buffer for req-data timing). signal idxA_valid : std_logic; signal idxA_ready : std_logic; signal idxA_index : std_logic_vector(INDEX_WIDTH-1 downto 0); - -- Index stream stage A (between buffer and sync). + -- Index stream stage A (between buffer for req-data timing and sync). signal idxB_valid : std_logic; signal idxB_ready : std_logic; signal idxB_index : std_logic_vector(INDEX_WIDTH-1 downto 0); signal idxB_enable : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); - -- Demultiplexed serialized response stream handshake signals. + -- Index stream stage A (between sync and buffer for req-resp timing). + signal idxC_valid : std_logic; + signal idxC_ready : std_logic; + signal idxC_index : std_logic_vector(INDEX_WIDTH-1 downto 0); + + -- Index stream stage A (between buffer for req-resp timing and sync). + signal idxD_valid : std_logic; + signal idxD_ready : std_logic; + signal idxD_index : std_logic_vector(INDEX_WIDTH-1 downto 0); + signal idxD_enable : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + + -- Multiplexed data stream signals. signal mux_wdat_valid : std_logic; signal mux_wdat_ready : std_logic; signal mux_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal mux_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal mux_wdat_last : std_logic; + -- Demultiplexed serialized response stream handshake signals. + signal demux_valid : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + signal demux_ready : std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + begin -- Connect the serialized slave ports to the internal arrays for convenience. @@ -203,19 +252,25 @@ begin bsv_wreq_ready(i) <= bs_wreq_ready (i); bs_wreq_addr (i) <= bsv_wreq_addr ((i+1)*BUS_ADDR_WIDTH-1 downto i*BUS_ADDR_WIDTH); bs_wreq_len (i) <= bsv_wreq_len ((i+1)*BUS_LEN_WIDTH-1 downto i*BUS_LEN_WIDTH); + bs_wreq_last (i) <= bsv_wreq_last (i); bs_wdat_valid (i) <= bsv_wdat_valid(i); bsv_wdat_ready(i) <= bs_wdat_ready (i); bs_wdat_data (i) <= bsv_wdat_data((i+1)*BUS_DATA_WIDTH-1 downto i*BUS_DATA_WIDTH); bs_wdat_strobe(i) <= bsv_wdat_strobe((i+1)*BUS_DATA_WIDTH/8-1 downto i*BUS_DATA_WIDTH/8); bs_wdat_last (i) <= bsv_wdat_last (i); + bsv_wrep_valid(i) <= bs_wrep_valid (i); + bs_wrep_ready (i) <= bsv_wrep_ready(i); + bsv_wrep_ok (i) <= bs_wrep_ok (i); end generate; -- Instantiate register slices for the slave ports. slave_slice_gen: for i in 0 to NUM_SLAVE_PORTS-1 generate signal wreqi_sData : std_logic_vector(BQI(BQI'high)-1 downto 0); signal wreqo_sData : std_logic_vector(BQI(BQI'high)-1 downto 0); - signal wdati_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); - signal wdato_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); + signal wdati_sData : std_logic_vector(BDI(BDI'high)-1 downto 0); + signal wdato_sData : std_logic_vector(BDI(BDI'high)-1 downto 0); + signal wrepi_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); + signal wrepo_sData : std_logic_vector(BPI(BPI'high)-1 downto 0); begin -- Request register slice. @@ -237,9 +292,11 @@ begin out_data => wreqo_sData ); + wreqi_sData(BQI(2)) <= bs_wreq_last(i); wreqi_sData(BQI(2)-1 downto BQI(1)) <= bs_wreq_addr(i); wreqi_sData(BQI(1)-1 downto BQI(0)) <= bs_wreq_len(i); + bss_wreq_last(i) <= wreqo_sData(BQI(2)); bss_wreq_addr(i) <= wreqo_sData(BQI(2)-1 downto BQI(1)); bss_wreq_len(i) <= wreqo_sData(BQI(1)-1 downto BQI(0)); @@ -247,7 +304,7 @@ begin dat_buffer_inst: StreamBuffer generic map ( MIN_DEPTH => sel(SLV_DAT_SLICES, 2, 0), - DATA_WIDTH => BPI(BPI'high) + DATA_WIDTH => BDI(BDI'high) ) port map ( clk => bcd_clk, @@ -262,13 +319,36 @@ begin out_data => wdato_sData ); - wdati_sData(BPI(3)-1 downto BPI(2)) <= bs_wdat_strobe(i); - wdati_sData(BPI(2)-1 downto BPI(1)) <= bs_wdat_data(i); - wdati_sData(BPI(0)) <= bs_wdat_last(i); + wdati_sData(BDI(3)-1 downto BDI(2)) <= bs_wdat_strobe(i); + wdati_sData(BDI(2)-1 downto BDI(1)) <= bs_wdat_data(i); + wdati_sData(BDI(0)) <= bs_wdat_last(i); - bss_wdat_strobe(i) <= wdato_sData(BPI(3)-1 downto BPI(2)); - bss_wdat_data(i) <= wdato_sData(BPI(2)-1 downto BPI(1)); - bss_wdat_last(i) <= wdato_sData(BPI(0)); + bss_wdat_strobe(i) <= wdato_sData(BDI(3)-1 downto BDI(2)); + bss_wdat_data(i) <= wdato_sData(BDI(2)-1 downto BDI(1)); + bss_wdat_last(i) <= wdato_sData(BDI(0)); + + -- Write data register slice. + rep_buffer_inst: StreamBuffer + generic map ( + MIN_DEPTH => sel(SLV_REP_SLICES, 2, 0), + DATA_WIDTH => BPI(BPI'high) + ) + port map ( + clk => bcd_clk, + reset => bcd_reset, + + in_valid => bss_wrep_valid(i), + in_ready => bss_wrep_ready(i), + in_data => wrepi_sData, + + out_valid => bs_wrep_valid(i), + out_ready => bs_wrep_ready(i), + out_data => wrepo_sData + ); + + wrepi_sData(BPI(0)) <= bss_wrep_ok(i); + + bs_wrep_ok(i) <= wrepo_sData(BPI(0)); end generate; @@ -291,9 +371,11 @@ begin out_data => mreqo_sData ); + mreqi_sData(BQI(2)) <= bms_wreq_last; mreqi_sData(BQI(2)-1 downto BQI(1)) <= bms_wreq_addr; mreqi_sData(BQI(1)-1 downto BQI(0)) <= bms_wreq_len; + mst_wreq_last <= mreqo_sData(BQI(2)); mst_wreq_addr <= mreqo_sData(BQI(2)-1 downto BQI(1)); mst_wreq_len <= mreqo_sData(BQI(1)-1 downto BQI(0)); @@ -301,7 +383,7 @@ begin mst_wdat_buffer_inst: StreamBuffer generic map ( MIN_DEPTH => sel(MST_DAT_SLICE, 2, 0), - DATA_WIDTH => BPI(BPI'high) + DATA_WIDTH => BDI(BDI'high) ) port map ( clk => bcd_clk, @@ -316,19 +398,43 @@ begin out_data => mwdato_sData ); - mwdati_sData(BPI(3)-1 downto BPI(2)) <= bms_wdat_strobe; - mwdati_sData(BPI(2)-1 downto BPI(1)) <= bms_wdat_data; - mwdati_sData(BPI(0)) <= bms_wdat_last; + mwdati_sData(BDI(3)-1 downto BDI(2)) <= bms_wdat_strobe; + mwdati_sData(BDI(2)-1 downto BDI(1)) <= bms_wdat_data; + mwdati_sData(BDI(0)) <= bms_wdat_last; - mst_wdat_strobe <= mwdato_sData(BPI(3)-1 downto BPI(2)); - mst_wdat_data <= mwdato_sData(BPI(2)-1 downto BPI(1)); - mst_wdat_last <= mwdato_sData(BPI(0)); + mst_wdat_strobe <= mwdato_sData(BDI(3)-1 downto BDI(2)); + mst_wdat_data <= mwdato_sData(BDI(2)-1 downto BDI(1)); + mst_wdat_last <= mwdato_sData(BDI(0)); + + -- Instantiate master write response register slice. + mst_wrep_buffer_inst: StreamBuffer + generic map ( + MIN_DEPTH => sel(MST_REP_SLICE, 2, 0), + DATA_WIDTH => BPI(BPI'high) + ) + port map ( + clk => bcd_clk, + reset => bcd_reset, + + in_valid => mst_wrep_valid, + in_ready => mst_wrep_ready, + in_data => mwrepi_sData, + + out_valid => bms_wrep_valid, + out_ready => bms_wrep_ready, + out_data => mwrepo_sData + ); + + mwrepi_sData(BPI(0)) <= mst_wrep_ok; + + bms_wrep_ok <= mwrepo_sData(BPI(0)); -- Concatenate the arbiter input stream signals. - bss2arb_proc: process (bss_wreq_valid, bss_wreq_addr, bss_wreq_len) is + bss2arb_proc: process (bss_wreq_valid, bss_wreq_addr, bss_wreq_len, bss_wreq_last) is begin for i in 0 to NUM_SLAVE_PORTS-1 loop arb_in_valid(i) <= bss_wreq_valid(i); + arb_in_data(i*BQI(BQI'high)+BQI(2)) <= bss_wreq_last(i); arb_in_data(i*BQI(BQI'high)+BQI(2)-1 downto i*BQI(BQI'high)+BQI(1)) <= bss_wreq_addr(i); arb_in_data(i*BQI(BQI'high)+BQI(1)-1 downto i*BQI(BQI'high)+BQI(0)) <= bss_wreq_len(i); end loop; @@ -362,6 +468,7 @@ begin out_index => idxA_index ); + bms_wreq_last <= arbo_sData(BQI(2)); bms_wreq_addr <= arbo_sData(BQI(2)-1 downto BQI(1)); bms_wreq_len <= arbo_sData(BQI(1)-1 downto BQI(0)); @@ -370,23 +477,25 @@ begin arb_sync_inst: StreamSync generic map ( NUM_INPUTS => 1, - NUM_OUTPUTS => 2 + NUM_OUTPUTS => 3 ) port map ( clk => bcd_clk, reset => bcd_reset, in_valid(0) => arb_out_valid, in_ready(0) => arb_out_ready, - out_valid(1) => bms_wreq_valid, - out_valid(0) => idxA_valid, - out_ready(1) => bms_wreq_ready, - out_ready(0) => idxA_ready + out_valid(2) => bms_wreq_valid, + out_valid(1) => idxA_valid, + out_valid(0) => idxC_valid, + out_ready(2) => bms_wreq_ready, + out_ready(1) => idxA_ready, + out_ready(0) => idxC_ready ); - -- Instantiate the outstanding request buffer. - index_buffer_inst: StreamBuffer + -- Instantiate write command to write data buffer. + index_data_buffer_inst: StreamBuffer generic map ( - MIN_DEPTH => MAX_OUTSTANDING, + MIN_DEPTH => 2, DATA_WIDTH => INDEX_WIDTH, RAM_CONFIG => RAM_CONFIG ) @@ -477,5 +586,76 @@ begin bms_wdat_data <= mux_wdat_data; bms_wdat_last <= mux_wdat_last; + -- Instantiate the outstanding request buffer. + index_resp_buffer_inst: StreamBuffer + generic map ( + MIN_DEPTH => MAX_OUTSTANDING, + DATA_WIDTH => INDEX_WIDTH, + RAM_CONFIG => RAM_CONFIG + ) + port map ( + clk => bcd_clk, + reset => bcd_reset, + + in_valid => idxC_valid, + in_ready => idxC_ready, + in_data => idxC_index, + + out_valid => idxD_valid, + out_ready => idxD_ready, + out_data => idxD_index + ); + + -- Decode the index signal to one-hot for the response synchronizer. + resp_index_to_oh_proc: process (idxD_index) is + begin + for i in 0 to NUM_SLAVE_PORTS-1 loop + if to_integer(unsigned(idxD_index)) = i then + idxD_enable(i) <= '1'; + else + idxD_enable(i) <= '0'; + end if; + end loop; + end process; + + -- Synchronize response channels. + resp_sync_inst: StreamSync + generic map ( + NUM_INPUTS => 2, + NUM_OUTPUTS => NUM_SLAVE_PORTS + ) + port map ( + clk => bcd_clk, + reset => bcd_reset, + + in_valid(1) => idxD_valid, + in_valid(0) => bms_wrep_valid, + in_ready(1) => idxD_ready, + in_ready(0) => bms_wrep_ready, + + out_valid => demux_valid, + out_ready => demux_ready, + out_enable => idxD_enable + ); + + -- Serialize/deserialize the demultiplexer signals. Also connect the ok + -- signal from the slave response slice directly to all the master + -- reponse slices. Only the handshake signals differ here. + demux2bms_proc: process (demux_valid, bms_wrep_ok) is + begin + for i in 0 to NUM_SLAVE_PORTS-1 loop + bss_wrep_valid(i) <= demux_valid(i); + bss_wrep_ok(i) <= bms_wrep_ok; + end loop; + end process; + bms2demux_proc: process (bss_wrep_ready) is + begin + for i in 0 to NUM_SLAVE_PORTS-1 loop + demux_ready(i) <= bss_wrep_ready(i); + end loop; + end process; + + + end Behavioral; diff --git a/hardware/interconnect/BusWriteBuffer.vhd b/hardware/interconnect/BusWriteBuffer.vhd index e80fdfde2..8d5cc2f62 100644 --- a/hardware/interconnect/BusWriteBuffer.vhd +++ b/hardware/interconnect/BusWriteBuffer.vhd @@ -73,7 +73,10 @@ entity BusWriteBuffer is SLV_DAT_SLICE : boolean := true; -- Instantiate a slice on the write data channel on the master port - MST_DAT_SLICE : boolean := true + MST_DAT_SLICE : boolean := true; + + -- Instantiate a slice on the write response channel + REP_SLICE : boolean := true ); port ( @@ -98,6 +101,7 @@ entity BusWriteBuffer is slv_wreq_ready : out std_logic; slv_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); slv_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + slv_wreq_last : in std_logic; slv_wdat_valid : in std_logic; slv_wdat_ready : out std_logic; @@ -106,6 +110,10 @@ entity BusWriteBuffer is slv_wdat_last : in std_logic; slv_wdat_ctrl : in std_logic_vector(CTRL_WIDTH-1 downto 0) := (others => 'U'); + slv_wrep_valid : out std_logic; + slv_wrep_ready : in std_logic; + slv_wrep_ok : out std_logic; + --------------------------------------------------------------------------- -- Master ports. --------------------------------------------------------------------------- @@ -113,13 +121,18 @@ entity BusWriteBuffer is mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); mst_wdat_last : out std_logic; - mst_wdat_ctrl : out std_logic_vector(CTRL_WIDTH-1 downto 0) + mst_wdat_ctrl : out std_logic_vector(CTRL_WIDTH-1 downto 0); + + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic ); end BusWriteBuffer; @@ -132,6 +145,7 @@ architecture Behavioral of BusWriteBuffer is -- Request stream serialization indices. constant RSI : nat_array := cumulative(( + 2 => 1, 1 => BUS_LEN_WIDTH, 0 => BUS_ADDR_WIDTH )); @@ -149,6 +163,7 @@ architecture Behavioral of BusWriteBuffer is signal s_mst_wreq_ready : std_logic; signal s_mst_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal s_mst_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal s_mst_wreq_last : std_logic; signal s_mst_wreq_all : std_logic_vector(RSI(2)-1 downto 0); signal mst_wreq_all : std_logic_vector(RSI(2)-1 downto 0); @@ -156,6 +171,7 @@ architecture Behavioral of BusWriteBuffer is signal s_slv_wreq_ready : std_logic; signal s_slv_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal s_slv_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal s_slv_wreq_last : std_logic; signal s_slv_wreq_all : std_logic_vector(RSI(2)-1 downto 0); signal slv_wreq_all : std_logic_vector(RSI(2)-1 downto 0); @@ -194,6 +210,7 @@ architecture Behavioral of BusWriteBuffer is wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wreq_last : std_logic; end record; signal r : reg_record; @@ -205,6 +222,7 @@ architecture Behavioral of BusWriteBuffer is mst_wreq_valid : std_logic; mst_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : std_logic; fifo_out_ready : std_logic; @@ -237,7 +255,7 @@ begin comb_proc: process(r, fifo_in_valid, fifo_in_ready, fifo_out_valid, fifo_out_data(FDI(0)), - s_slv_wreq_len, s_slv_wreq_addr, s_slv_wreq_valid, + s_slv_wreq_last, s_slv_wreq_len, s_slv_wreq_addr, s_slv_wreq_valid, s_mst_wreq_ready, s_mst_wdat_ready ) is @@ -260,6 +278,7 @@ begin vo.mst_wreq_addr := vr.wreq_addr; vo.mst_wreq_len := vr.wreq_len; + vo.mst_wreq_last := vr.wreq_last; case vr.state is when IDLE => @@ -267,6 +286,7 @@ begin -- A request is made, register it. if s_slv_wreq_valid = '1' then + vr.wreq_last := s_slv_wreq_last; vr.wreq_len := s_slv_wreq_len; vr.wreq_addr := s_slv_wreq_addr; vr.state := REQ; @@ -276,6 +296,7 @@ begin -- Make the request valid on the master port vo.mst_wreq_addr := vr.wreq_addr; vo.mst_wreq_len := vr.wreq_len; + vo.mst_wreq_last := vr.wreq_last; -- Validate only when enough words have been loaded into the FIFO if vr.count >= unsigned(vr.wreq_len) then @@ -326,6 +347,7 @@ begin -- A request is made, register it. if s_slv_wreq_valid = '1' then vo.slv_wreq_ready := '1'; + vr.wreq_last := s_slv_wreq_last; vr.wreq_len := s_slv_wreq_len; vr.wreq_addr := s_slv_wreq_addr; vr.state := REQ; @@ -363,6 +385,7 @@ begin s_mst_wreq_valid <= vo.mst_wreq_valid; s_mst_wreq_addr <= vo.mst_wreq_addr; s_mst_wreq_len <= vo.mst_wreq_len; + s_mst_wreq_last <= vo.mst_wreq_last; s_mst_wdat_valid <= vo.mst_wdat_valid; s_mst_wdat_last <= vo.mst_wdat_last; @@ -475,13 +498,14 @@ begin ----------------------------------------------------------------------------- -- Slave write request channel slice ----------------------------------------------------------------------------- + slv_wreq_all(RSI(2)) <= slv_wreq_last; slv_wreq_all(RSI(2)-1 downto RSI(1)) <= slv_wreq_len; slv_wreq_all(RSI(1)-1 downto RSI(0)) <= slv_wreq_addr; slave_wreq_slice : StreamBuffer generic map ( MIN_DEPTH => sel(SLV_REQ_SLICE, 2, 0), - DATA_WIDTH => RSI(2) + DATA_WIDTH => RSI(3) ) port map ( clk => clk, @@ -496,19 +520,21 @@ begin out_data => s_slv_wreq_all ); + s_slv_wreq_last <= s_slv_wreq_all(RSI(2)); s_slv_wreq_len <= s_slv_wreq_all(RSI(2)-1 downto RSI(1)); s_slv_wreq_addr <= s_slv_wreq_all(RSI(1)-1 downto RSI(0)); ----------------------------------------------------------------------------- -- Master write request channel slice ----------------------------------------------------------------------------- + s_mst_wreq_all(RSI(2)) <= s_mst_wreq_last; s_mst_wreq_all(RSI(2)-1 downto RSI(1)) <= s_mst_wreq_len; s_mst_wreq_all(RSI(1)-1 downto RSI(0)) <= s_mst_wreq_addr; master_wreq_slice : StreamBuffer generic map ( MIN_DEPTH => sel(MST_REQ_SLICE, 2, 0), - DATA_WIDTH => RSI(2) + DATA_WIDTH => RSI(3) ) port map ( clk => clk, @@ -523,8 +549,29 @@ begin out_data => mst_wreq_all ); + mst_wreq_last <= mst_wreq_all(RSI(2)); mst_wreq_len <= mst_wreq_all(RSI(2)-1 downto RSI(1)); mst_wreq_addr <= mst_wreq_all(RSI(1)-1 downto RSI(0)); + ----------------------------------------------------------------------------- + -- Write response channel slice + ----------------------------------------------------------------------------- + wrep_slice : StreamBuffer + generic map ( + MIN_DEPTH => sel(REP_SLICE, 2, 0), + DATA_WIDTH => 1 + ) + port map ( + clk => clk, + reset => reset, + + in_valid => mst_wrep_valid, + in_ready => mst_wrep_ready, + in_data(0) => mst_wrep_ok, + + out_valid => slv_wrep_valid, + out_ready => slv_wrep_ready, + out_data(0) => slv_wrep_ok + ); end Behavioral; diff --git a/hardware/interconnect/Interconnect_pkg.vhd b/hardware/interconnect/Interconnect_pkg.vhd index b8d625154..c5199f9d9 100644 --- a/hardware/interconnect/Interconnect_pkg.vhd +++ b/hardware/interconnect/Interconnect_pkg.vhd @@ -80,37 +80,47 @@ package Interconnect_pkg is BUS_LEN_WIDTH : natural := 8; BUS_DATA_WIDTH : natural := 32; NUM_SLAVE_PORTS : natural := 2; - ARB_METHOD : string := "ROUND-ROBIN"; + ARB_METHOD : string := "ROUND-ROBIN"; MAX_OUTSTANDING : natural := 2; - RAM_CONFIG : string := ""; - SLV_REQ_SLICES : boolean := true; + RAM_CONFIG : string := ""; + SLV_REQ_SLICES : boolean := false; MST_REQ_SLICE : boolean := true; + SLV_DAT_SLICES : boolean := false; MST_DAT_SLICE : boolean := true; - SLV_DAT_SLICES : boolean := true + MST_REP_SLICE : boolean := false; + SLV_REP_SLICES : boolean := true ); port ( bcd_clk : in std_logic; bcd_reset : in std_logic; - + bsv_wreq_valid : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wreq_ready : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wreq_addr : in std_logic_vector(NUM_SLAVE_PORTS*BUS_ADDR_WIDTH-1 downto 0); bsv_wreq_len : in std_logic_vector(NUM_SLAVE_PORTS*BUS_LEN_WIDTH-1 downto 0); + bsv_wreq_last : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_valid : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_ready : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); bsv_wdat_data : in std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH-1 downto 0); bsv_wdat_strobe : in std_logic_vector(NUM_SLAVE_PORTS*BUS_DATA_WIDTH/8-1 downto 0); bsv_wdat_last : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); - + bsv_wrep_valid : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + bsv_wrep_ready : in std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + bsv_wrep_ok : out std_logic_vector(NUM_SLAVE_PORTS-1 downto 0); + mst_wreq_valid : out std_logic; mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - mst_wdat_last : out std_logic + mst_wdat_last : out std_logic; + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic ); end component; @@ -163,7 +173,8 @@ package Interconnect_pkg is SLV_REQ_SLICE : boolean := true; MST_REQ_SLICE : boolean := true; SLV_DAT_SLICE : boolean := true; - MST_DAT_SLICE : boolean := true + MST_DAT_SLICE : boolean := true; + REP_SLICE : boolean := true ); port ( clk : in std_logic; @@ -176,23 +187,31 @@ package Interconnect_pkg is slv_wreq_ready : out std_logic; slv_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); slv_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + slv_wreq_last : in std_logic; slv_wdat_valid : in std_logic; slv_wdat_ready : out std_logic; slv_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); slv_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); slv_wdat_ctrl : in std_logic_vector(CTRL_WIDTH-1 downto 0) := (others => 'U'); slv_wdat_last : in std_logic; + slv_wrep_valid : out std_logic; + slv_wrep_ready : in std_logic; + slv_wrep_ok : out std_logic; mst_wreq_valid : out std_logic; mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); mst_wdat_ctrl : out std_logic_vector(CTRL_WIDTH-1 downto 0); - mst_wdat_last : out std_logic + mst_wdat_last : out std_logic; + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic ); end component; @@ -373,17 +392,19 @@ package Interconnect_pkg is component BusWriteArbiter is generic ( - BUS_ADDR_WIDTH : natural; - BUS_LEN_WIDTH : natural; - BUS_DATA_WIDTH : natural; - NUM_SLAVE_PORTS : natural; - ARB_METHOD : string; - MAX_OUTSTANDING : natural; - RAM_CONFIG : string; - SLV_REQ_SLICES : boolean; - MST_REQ_SLICE : boolean; - MST_DAT_SLICE : boolean; - SLV_DAT_SLICES : boolean + BUS_ADDR_WIDTH : natural := 32; + BUS_LEN_WIDTH : natural := 8; + BUS_DATA_WIDTH : natural := 32; + NUM_SLAVE_PORTS : natural := 2; + ARB_METHOD : string := "ROUND-ROBIN"; + MAX_OUTSTANDING : natural := 2; + RAM_CONFIG : string := ""; + SLV_REQ_SLICES : boolean := true; + MST_REQ_SLICE : boolean := true; + SLV_DAT_SLICES : boolean := true; + MST_DAT_SLICE : boolean := true; + MST_REP_SLICE : boolean := true; + SLV_REP_SLICES : boolean := true ); port ( bcd_clk : in std_logic; @@ -393,192 +414,244 @@ package Interconnect_pkg is mst_wreq_ready : in std_logic; mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + mst_wreq_last : out std_logic; mst_wdat_valid : out std_logic; mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); mst_wdat_last : out std_logic; + mst_wrep_valid : in std_logic; + mst_wrep_ready : out std_logic; + mst_wrep_ok : in std_logic; -- Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn - -- Slave port 0. bs00_wreq_valid : in std_logic := '0'; bs00_wreq_ready : out std_logic; bs00_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs00_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs00_wreq_last : in std_logic := '0'; bs00_wdat_valid : in std_logic := '0'; - bs00_wdat_ready : out std_logic := '1'; + bs00_wdat_ready : out std_logic; bs00_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs00_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs00_wdat_last : in std_logic := 'U'; + bs00_wrep_valid : out std_logic; + bs00_wrep_ready : in std_logic := '1'; + bs00_wrep_ok : out std_logic; - -- Slave port 1. bs01_wreq_valid : in std_logic := '0'; bs01_wreq_ready : out std_logic; bs01_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs01_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs01_wreq_last : in std_logic := '0'; bs01_wdat_valid : in std_logic := '0'; - bs01_wdat_ready : out std_logic := '1'; + bs01_wdat_ready : out std_logic; bs01_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs01_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs01_wdat_last : in std_logic := 'U'; + bs01_wrep_valid : out std_logic; + bs01_wrep_ready : in std_logic := '1'; + bs01_wrep_ok : out std_logic; - -- Slave port 2. bs02_wreq_valid : in std_logic := '0'; bs02_wreq_ready : out std_logic; bs02_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs02_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs02_wreq_last : in std_logic := '0'; bs02_wdat_valid : in std_logic := '0'; - bs02_wdat_ready : out std_logic := '1'; + bs02_wdat_ready : out std_logic; bs02_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs02_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs02_wdat_last : in std_logic := 'U'; + bs02_wrep_valid : out std_logic; + bs02_wrep_ready : in std_logic := '1'; + bs02_wrep_ok : out std_logic; - -- Slave port 3. bs03_wreq_valid : in std_logic := '0'; bs03_wreq_ready : out std_logic; bs03_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs03_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs03_wreq_last : in std_logic := '0'; bs03_wdat_valid : in std_logic := '0'; - bs03_wdat_ready : out std_logic := '1'; + bs03_wdat_ready : out std_logic; bs03_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs03_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs03_wdat_last : in std_logic := 'U'; + bs03_wrep_valid : out std_logic; + bs03_wrep_ready : in std_logic := '1'; + bs03_wrep_ok : out std_logic; - -- Slave port 4. bs04_wreq_valid : in std_logic := '0'; bs04_wreq_ready : out std_logic; bs04_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs04_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs04_wreq_last : in std_logic := '0'; bs04_wdat_valid : in std_logic := '0'; - bs04_wdat_ready : out std_logic := '1'; + bs04_wdat_ready : out std_logic; bs04_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs04_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs04_wdat_last : in std_logic := 'U'; + bs04_wrep_valid : out std_logic; + bs04_wrep_ready : in std_logic := '1'; + bs04_wrep_ok : out std_logic; - -- Slave port 5. bs05_wreq_valid : in std_logic := '0'; bs05_wreq_ready : out std_logic; bs05_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs05_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs05_wreq_last : in std_logic := '0'; bs05_wdat_valid : in std_logic := '0'; - bs05_wdat_ready : out std_logic := '1'; + bs05_wdat_ready : out std_logic; bs05_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs05_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs05_wdat_last : in std_logic := 'U'; + bs05_wrep_valid : out std_logic; + bs05_wrep_ready : in std_logic := '1'; + bs05_wrep_ok : out std_logic; - -- Slave port 6. bs06_wreq_valid : in std_logic := '0'; bs06_wreq_ready : out std_logic; bs06_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs06_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs06_wreq_last : in std_logic := '0'; bs06_wdat_valid : in std_logic := '0'; - bs06_wdat_ready : out std_logic := '1'; + bs06_wdat_ready : out std_logic; bs06_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs06_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs06_wdat_last : in std_logic := 'U'; + bs06_wrep_valid : out std_logic; + bs06_wrep_ready : in std_logic := '1'; + bs06_wrep_ok : out std_logic; - -- Slave port 7. bs07_wreq_valid : in std_logic := '0'; bs07_wreq_ready : out std_logic; bs07_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs07_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs07_wreq_last : in std_logic := '0'; bs07_wdat_valid : in std_logic := '0'; - bs07_wdat_ready : out std_logic := '1'; + bs07_wdat_ready : out std_logic; bs07_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs07_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs07_wdat_last : in std_logic := 'U'; + bs07_wrep_valid : out std_logic; + bs07_wrep_ready : in std_logic := '1'; + bs07_wrep_ok : out std_logic; - -- Slave port 8. bs08_wreq_valid : in std_logic := '0'; bs08_wreq_ready : out std_logic; bs08_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs08_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs08_wreq_last : in std_logic := '0'; bs08_wdat_valid : in std_logic := '0'; - bs08_wdat_ready : out std_logic := '1'; + bs08_wdat_ready : out std_logic; bs08_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs08_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs08_wdat_last : in std_logic := 'U'; + bs08_wrep_valid : out std_logic; + bs08_wrep_ready : in std_logic := '1'; + bs08_wrep_ok : out std_logic; - -- Slave port 9. bs09_wreq_valid : in std_logic := '0'; bs09_wreq_ready : out std_logic; bs09_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs09_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs09_wreq_last : in std_logic := '0'; bs09_wdat_valid : in std_logic := '0'; - bs09_wdat_ready : out std_logic := '1'; + bs09_wdat_ready : out std_logic; bs09_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs09_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs09_wdat_last : in std_logic := 'U'; + bs09_wrep_valid : out std_logic; + bs09_wrep_ready : in std_logic := '1'; + bs09_wrep_ok : out std_logic; - -- Slave port 10. bs10_wreq_valid : in std_logic := '0'; bs10_wreq_ready : out std_logic; bs10_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs10_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs10_wreq_last : in std_logic := '0'; bs10_wdat_valid : in std_logic := '0'; - bs10_wdat_ready : out std_logic := '1'; + bs10_wdat_ready : out std_logic; bs10_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs10_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs10_wdat_last : in std_logic := 'U'; + bs10_wrep_valid : out std_logic; + bs10_wrep_ready : in std_logic := '1'; + bs10_wrep_ok : out std_logic; - -- Slave port 11. bs11_wreq_valid : in std_logic := '0'; bs11_wreq_ready : out std_logic; bs11_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs11_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs11_wreq_last : in std_logic := '0'; bs11_wdat_valid : in std_logic := '0'; - bs11_wdat_ready : out std_logic := '1'; + bs11_wdat_ready : out std_logic; bs11_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs11_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs11_wdat_last : in std_logic := 'U'; + bs11_wrep_valid : out std_logic; + bs11_wrep_ready : in std_logic := '1'; + bs11_wrep_ok : out std_logic; - -- Slave port 12. bs12_wreq_valid : in std_logic := '0'; bs12_wreq_ready : out std_logic; bs12_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs12_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs12_wreq_last : in std_logic := '0'; bs12_wdat_valid : in std_logic := '0'; - bs12_wdat_ready : out std_logic := '1'; + bs12_wdat_ready : out std_logic; bs12_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs12_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs12_wdat_last : in std_logic := 'U'; + bs12_wrep_valid : out std_logic; + bs12_wrep_ready : in std_logic := '1'; + bs12_wrep_ok : out std_logic; - -- Slave port 13. bs13_wreq_valid : in std_logic := '0'; bs13_wreq_ready : out std_logic; bs13_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs13_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs13_wreq_last : in std_logic := '0'; bs13_wdat_valid : in std_logic := '0'; - bs13_wdat_ready : out std_logic := '1'; + bs13_wdat_ready : out std_logic; bs13_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs13_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs13_wdat_last : in std_logic := 'U'; + bs13_wrep_valid : out std_logic; + bs13_wrep_ready : in std_logic := '1'; + bs13_wrep_ok : out std_logic; - -- Slave port 14. bs14_wreq_valid : in std_logic := '0'; bs14_wreq_ready : out std_logic; bs14_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs14_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs14_wreq_last : in std_logic := '0'; bs14_wdat_valid : in std_logic := '0'; - bs14_wdat_ready : out std_logic := '1'; + bs14_wdat_ready : out std_logic; bs14_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs14_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); bs14_wdat_last : in std_logic := 'U'; + bs14_wrep_valid : out std_logic; + bs14_wrep_ready : in std_logic := '1'; + bs14_wrep_ok : out std_logic; - -- Slave port 15. bs15_wreq_valid : in std_logic := '0'; bs15_wreq_ready : out std_logic; bs15_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0) := (others => '0'); bs15_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0) := (others => '0'); + bs15_wreq_last : in std_logic := '0'; bs15_wdat_valid : in std_logic := '0'; - bs15_wdat_ready : out std_logic := '1'; + bs15_wdat_ready : out std_logic; bs15_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0) := (others => 'U'); bs15_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0) := (others => 'U'); - bs15_wdat_last : in std_logic := 'U' + bs15_wdat_last : in std_logic := 'U'; + bs15_wrep_valid : out std_logic; + bs15_wrep_ready : in std_logic := '1'; + bs15_wrep_ok : out std_logic ); end component; - + ----------------------------------------------------------------------------- -- Component declarations for simulation-only helper units ----------------------------------------------------------------------------- @@ -644,11 +717,15 @@ package Interconnect_pkg is wreq_ready : in std_logic; wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wreq_last : out std_logic; wdat_valid : out std_logic; wdat_ready : in std_logic; wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - wdat_last : out std_logic + wdat_last : out std_logic; + wrep_valid : in std_logic; + wrep_ready : out std_logic; + wrep_ok : in std_logic ); end component; @@ -669,11 +746,15 @@ package Interconnect_pkg is wreq_ready : out std_logic; wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wreq_last : in std_logic; wdat_valid : in std_logic; wdat_ready : out std_logic; wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - wdat_last : in std_logic + wdat_last : in std_logic; + wrep_valid : out std_logic; + wrep_ready : in std_logic; + wrep_ok : out std_logic ); end component; diff --git a/hardware/interconnect/test/BusChecking_pkg.vhd b/hardware/interconnect/test/BusChecking_pkg.vhd index 0a5382bae..06cc53c7d 100644 --- a/hardware/interconnect/test/BusChecking_pkg.vhd +++ b/hardware/interconnect/test/BusChecking_pkg.vhd @@ -45,11 +45,15 @@ package BusChecking_pkg is bus_wreq_ready : in std_logic; bus_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : in std_logic; bus_wdat_valid : in std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - bus_wdat_last : in std_logic + bus_wdat_last : in std_logic; + bus_wrep_valid : in std_logic; + bus_wrep_ready : in std_logic; + bus_wrep_ok : in std_logic ); end component; diff --git a/hardware/interconnect/test/BusProtocolChecker.vhd b/hardware/interconnect/test/BusProtocolChecker.vhd index 68c329f60..6e1c60ce3 100644 --- a/hardware/interconnect/test/BusProtocolChecker.vhd +++ b/hardware/interconnect/test/BusProtocolChecker.vhd @@ -46,11 +46,15 @@ entity BusProtocolChecker is bus_wreq_ready : in std_logic; bus_wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : in std_logic; bus_wdat_valid : in std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - bus_wdat_last : in std_logic + bus_wdat_last : in std_logic; + bus_wrep_valid : in std_logic; + bus_wrep_ready : in std_logic; + bus_wrep_ok : in std_logic ); end BusProtocolChecker; diff --git a/hardware/interconnect/test/BusWriteArbiter_tb.vhd b/hardware/interconnect/test/BusWriteArbiter_tb.vhd index f1d229882..f4df10541 100644 --- a/hardware/interconnect/test/BusWriteArbiter_tb.vhd +++ b/hardware/interconnect/test/BusWriteArbiter_tb.vhd @@ -37,11 +37,15 @@ architecture Behavioral of BusWriteArbiter_tb is signal ma2b_wreq_ready : std_logic; signal ma2b_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal ma2b_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal ma2b_wreq_last : std_logic; signal ma2b_wdat_valid : std_logic := '0'; signal ma2b_wdat_ready : std_logic; signal ma2b_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal ma2b_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal ma2b_wdat_last : std_logic; + signal ma2b_wrep_valid : std_logic := '0'; + signal ma2b_wrep_ready : std_logic; + signal ma2b_wrep_ok : std_logic; signal ma2b_wdat_data_m : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal ma2b_wdat_last_m : std_logic; @@ -51,11 +55,15 @@ architecture Behavioral of BusWriteArbiter_tb is signal mb2b_wreq_ready : std_logic; signal mb2b_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal mb2b_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal mb2b_wreq_last : std_logic; signal mb2b_wdat_valid : std_logic := '0'; signal mb2b_wdat_ready : std_logic; signal mb2b_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal mb2b_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal mb2b_wdat_last : std_logic; + signal mb2b_wrep_valid : std_logic := '0'; + signal mb2b_wrep_ready : std_logic; + signal mb2b_wrep_ok : std_logic; signal mb2b_wdat_data_m : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal mb2b_wdat_last_m : std_logic; @@ -65,11 +73,15 @@ architecture Behavioral of BusWriteArbiter_tb is signal mc2b_wreq_ready : std_logic; signal mc2b_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal mc2b_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal mc2b_wreq_last : std_logic; signal mc2b_wdat_valid : std_logic := '0'; signal mc2b_wdat_ready : std_logic; signal mc2b_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal mc2b_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal mc2b_wdat_last : std_logic; + signal mc2b_wrep_valid : std_logic := '0'; + signal mc2b_wrep_ready : std_logic; + signal mc2b_wrep_ok : std_logic; signal mc2b_wdat_data_m : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal mc2b_wdat_last_m : std_logic; @@ -80,42 +92,58 @@ architecture Behavioral of BusWriteArbiter_tb is signal ba2a_wreq_ready : std_logic; signal ba2a_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal ba2a_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal ba2a_wreq_last : std_logic; signal ba2a_wdat_valid : std_logic := '0'; signal ba2a_wdat_ready : std_logic; signal ba2a_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal ba2a_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal ba2a_wdat_last : std_logic; + signal ba2a_wrep_valid : std_logic := '0'; + signal ba2a_wrep_ready : std_logic; + signal ba2a_wrep_ok : std_logic; signal bb2a_wreq_valid : std_logic := '0'; signal bb2a_wreq_ready : std_logic; signal bb2a_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bb2a_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bb2a_wreq_last : std_logic; signal bb2a_wdat_valid : std_logic := '0'; signal bb2a_wdat_ready : std_logic; signal bb2a_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bb2a_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal bb2a_wdat_last : std_logic; + signal bb2a_wrep_valid : std_logic := '0'; + signal bb2a_wrep_ready : std_logic; + signal bb2a_wrep_ok : std_logic; signal bc2a_wreq_valid : std_logic := '0'; signal bc2a_wreq_ready : std_logic; signal bc2a_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bc2a_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bc2a_wreq_last : std_logic; signal bc2a_wdat_valid : std_logic := '0'; signal bc2a_wdat_ready : std_logic; signal bc2a_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bc2a_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal bc2a_wdat_last : std_logic; + signal bc2a_wrep_valid : std_logic := '0'; + signal bc2a_wrep_ready : std_logic; + signal bc2a_wrep_ok : std_logic; -- Arbiter to slave. signal a2s_wreq_valid : std_logic := '0'; signal a2s_wreq_ready : std_logic; signal a2s_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal a2s_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal a2s_wreq_last : std_logic; signal a2s_wdat_valid : std_logic := '0'; signal a2s_wdat_ready : std_logic; signal a2s_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal a2s_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal a2s_wdat_last : std_logic; + signal a2s_wrep_valid : std_logic := '0'; + signal a2s_wrep_ready : std_logic; + signal a2s_wrep_ok : std_logic; begin @@ -160,11 +188,15 @@ begin wreq_ready => ma2b_wreq_ready, wreq_addr => ma2b_wreq_addr, wreq_len => ma2b_wreq_len, + wreq_last => ma2b_wreq_last, wdat_valid => ma2b_wdat_valid, wdat_ready => ma2b_wdat_ready, wdat_data => ma2b_wdat_data, wdat_strobe => ma2b_wdat_strobe, - wdat_last => ma2b_wdat_last + wdat_last => ma2b_wdat_last, + wrep_valid => ma2b_wrep_valid, + wrep_ready => ma2b_wrep_ready, + wrep_ok => ma2b_wrep_ok ); mst_a_buffer_inst: BusWriteBuffer @@ -185,21 +217,29 @@ begin slv_wreq_ready => ma2b_wreq_ready, slv_wreq_addr => ma2b_wreq_addr, slv_wreq_len => ma2b_wreq_len, + slv_wreq_last => ma2b_wreq_last, slv_wdat_valid => ma2b_wdat_valid, slv_wdat_ready => ma2b_wdat_ready, slv_wdat_data => ma2b_wdat_data, slv_wdat_strobe => ma2b_wdat_strobe, slv_wdat_last => ma2b_wdat_last, + slv_wrep_valid => ma2b_wrep_valid, + slv_wrep_ready => ma2b_wrep_ready, + slv_wrep_ok => ma2b_wrep_ok, mst_wreq_valid => ba2a_wreq_valid, mst_wreq_ready => ba2a_wreq_ready, mst_wreq_addr => ba2a_wreq_addr, mst_wreq_len => ba2a_wreq_len, + mst_wreq_last => ba2a_wreq_last, mst_wdat_valid => ba2a_wdat_valid, mst_wdat_ready => ba2a_wdat_ready, mst_wdat_data => ba2a_wdat_data, mst_wdat_strobe => ba2a_wdat_strobe, - mst_wdat_last => ba2a_wdat_last + mst_wdat_last => ba2a_wdat_last, + mst_wrep_valid => ba2a_wrep_valid, + mst_wrep_ready => ba2a_wrep_ready, + mst_wrep_ok => ba2a_wrep_ok ); mst_b_inst: BusWriteMasterMock @@ -216,11 +256,15 @@ begin wreq_ready => mb2b_wreq_ready, wreq_addr => mb2b_wreq_addr, wreq_len => mb2b_wreq_len, + wreq_last => mb2b_wreq_last, wdat_valid => mb2b_wdat_valid, wdat_ready => mb2b_wdat_ready, wdat_data => mb2b_wdat_data, wdat_strobe => mb2b_wdat_strobe, - wdat_last => mb2b_wdat_last + wdat_last => mb2b_wdat_last, + wrep_valid => mb2b_wrep_valid, + wrep_ready => mb2b_wrep_ready, + wrep_ok => mb2b_wrep_ok ); mst_b_buffer_inst: BusWriteBuffer @@ -241,21 +285,29 @@ begin slv_wreq_ready => mb2b_wreq_ready, slv_wreq_addr => mb2b_wreq_addr, slv_wreq_len => mb2b_wreq_len, + slv_wreq_last => mb2b_wreq_last, slv_wdat_valid => mb2b_wdat_valid, slv_wdat_ready => mb2b_wdat_ready, slv_wdat_data => mb2b_wdat_data, slv_wdat_strobe => mb2b_wdat_strobe, slv_wdat_last => mb2b_wdat_last, + slv_wrep_valid => mb2b_wrep_valid, + slv_wrep_ready => mb2b_wrep_ready, + slv_wrep_ok => mb2b_wrep_ok, mst_wreq_valid => bb2a_wreq_valid, mst_wreq_ready => bb2a_wreq_ready, mst_wreq_addr => bb2a_wreq_addr, mst_wreq_len => bb2a_wreq_len, + mst_wreq_last => bb2a_wreq_last, mst_wdat_valid => bb2a_wdat_valid, mst_wdat_ready => bb2a_wdat_ready, mst_wdat_data => bb2a_wdat_data, mst_wdat_strobe => bb2a_wdat_strobe, - mst_wdat_last => bb2a_wdat_last + mst_wdat_last => bb2a_wdat_last, + mst_wrep_valid => bb2a_wrep_valid, + mst_wrep_ready => bb2a_wrep_ready, + mst_wrep_ok => bb2a_wrep_ok ); mst_c_inst: BusWriteMasterMock @@ -272,11 +324,15 @@ begin wreq_ready => mc2b_wreq_ready, wreq_addr => mc2b_wreq_addr, wreq_len => mc2b_wreq_len, + wreq_last => mc2b_wreq_last, wdat_valid => mc2b_wdat_valid, wdat_ready => mc2b_wdat_ready, wdat_data => mc2b_wdat_data, wdat_strobe => mc2b_wdat_strobe, - wdat_last => mc2b_wdat_last + wdat_last => mc2b_wdat_last, + wrep_valid => mc2b_wrep_valid, + wrep_ready => mc2b_wrep_ready, + wrep_ok => mc2b_wrep_ok ); mst_c_buffer_inst: BusWriteBuffer @@ -297,21 +353,29 @@ begin slv_wreq_ready => mc2b_wreq_ready, slv_wreq_addr => mc2b_wreq_addr, slv_wreq_len => mc2b_wreq_len, + slv_wreq_last => mc2b_wreq_last, slv_wdat_valid => mc2b_wdat_valid, slv_wdat_ready => mc2b_wdat_ready, slv_wdat_data => mc2b_wdat_data, slv_wdat_strobe => mc2b_wdat_strobe, slv_wdat_last => mc2b_wdat_last, + slv_wrep_valid => mc2b_wrep_valid, + slv_wrep_ready => mc2b_wrep_ready, + slv_wrep_ok => mc2b_wrep_ok, mst_wreq_valid => bc2a_wreq_valid, mst_wreq_ready => bc2a_wreq_ready, mst_wreq_addr => bc2a_wreq_addr, mst_wreq_len => bc2a_wreq_len, + mst_wreq_last => bc2a_wreq_last, mst_wdat_valid => bc2a_wdat_valid, mst_wdat_ready => bc2a_wdat_ready, mst_wdat_data => bc2a_wdat_data, mst_wdat_strobe => bc2a_wdat_strobe, - mst_wdat_last => bc2a_wdat_last + mst_wdat_last => bc2a_wdat_last, + mst_wrep_valid => bc2a_wrep_valid, + mst_wrep_ready => bc2a_wrep_ready, + mst_wrep_ok => bc2a_wrep_ok ); uut: BusWriteArbiter @@ -336,41 +400,57 @@ begin mst_wreq_ready => a2s_wreq_ready, mst_wreq_addr => a2s_wreq_addr, mst_wreq_len => a2s_wreq_len, + mst_wreq_last => a2s_wreq_last, mst_wdat_valid => a2s_wdat_valid, mst_wdat_ready => a2s_wdat_ready, mst_wdat_data => a2s_wdat_data, mst_wdat_strobe => a2s_wdat_strobe, mst_wdat_last => a2s_wdat_last, + mst_wrep_valid => a2s_wrep_valid, + mst_wrep_ready => a2s_wrep_ready, + mst_wrep_ok => a2s_wrep_ok, bs00_wreq_valid => ba2a_wreq_valid, bs00_wreq_ready => ba2a_wreq_ready, bs00_wreq_addr => ba2a_wreq_addr, bs00_wreq_len => ba2a_wreq_len, + bs00_wreq_last => ba2a_wreq_last, bs00_wdat_valid => ba2a_wdat_valid, bs00_wdat_ready => ba2a_wdat_ready, bs00_wdat_data => ba2a_wdat_data, bs00_wdat_strobe => ba2a_wdat_strobe, bs00_wdat_last => ba2a_wdat_last, + bs00_wrep_valid => ba2a_wrep_valid, + bs00_wrep_ready => ba2a_wrep_ready, + bs00_wrep_ok => ba2a_wrep_ok, bs01_wreq_valid => bb2a_wreq_valid, bs01_wreq_ready => bb2a_wreq_ready, bs01_wreq_addr => bb2a_wreq_addr, bs01_wreq_len => bb2a_wreq_len, + bs01_wreq_last => bb2a_wreq_last, bs01_wdat_valid => bb2a_wdat_valid, bs01_wdat_ready => bb2a_wdat_ready, bs01_wdat_data => bb2a_wdat_data, bs01_wdat_strobe => bb2a_wdat_strobe, bs01_wdat_last => bb2a_wdat_last, + bs01_wrep_valid => bb2a_wrep_valid, + bs01_wrep_ready => bb2a_wrep_ready, + bs01_wrep_ok => bb2a_wrep_ok, bs02_wreq_valid => bc2a_wreq_valid, bs02_wreq_ready => bc2a_wreq_ready, bs02_wreq_addr => bc2a_wreq_addr, bs02_wreq_len => bc2a_wreq_len, + bs02_wreq_last => bc2a_wreq_last, bs02_wdat_valid => bc2a_wdat_valid, bs02_wdat_ready => bc2a_wdat_ready, bs02_wdat_data => bc2a_wdat_data, bs02_wdat_strobe => bc2a_wdat_strobe, - bs02_wdat_last => bc2a_wdat_last + bs02_wdat_last => bc2a_wdat_last, + bs02_wrep_valid => bc2a_wrep_valid, + bs02_wrep_ready => bc2a_wrep_ready, + bs02_wrep_ok => bc2a_wrep_ok ); slave_inst: BusWriteSlaveMock @@ -387,11 +467,15 @@ begin wreq_ready => a2s_wreq_ready, wreq_addr => a2s_wreq_addr, wreq_len => a2s_wreq_len, + wreq_last => a2s_wreq_last, wdat_valid => a2s_wdat_valid, wdat_ready => a2s_wdat_ready, wdat_data => a2s_wdat_data, wdat_strobe => a2s_wdat_strobe, - wdat_last => a2s_wdat_last + wdat_last => a2s_wdat_last, + wrep_valid => a2s_wrep_valid, + wrep_ready => a2s_wrep_ready, + wrep_ok => a2s_wrep_ok ); end Behavioral; diff --git a/hardware/interconnect/test/BusWriteMasterMock.vhd b/hardware/interconnect/test/BusWriteMasterMock.vhd index 34c89b57a..964b9421d 100644 --- a/hardware/interconnect/test/BusWriteMasterMock.vhd +++ b/hardware/interconnect/test/BusWriteMasterMock.vhd @@ -53,11 +53,15 @@ entity BusWriteMasterMock is wreq_ready : in std_logic; wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wreq_last : out std_logic; wdat_valid : out std_logic; wdat_ready : in std_logic; wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - wdat_last : out std_logic + wdat_last : out std_logic; + wrep_valid : in std_logic; + wrep_ready : out std_logic; + wrep_ok : in std_logic ); end BusWriteMasterMock; @@ -86,6 +90,7 @@ begin wreq_int_valid <= '0'; wreq_addr <= (others => '0'); wreq_len <= (others => '0'); + wreq_last <= '0'; wreq_valid <= '0'; wdat_valid <= '0'; @@ -143,5 +148,8 @@ begin end loop; end process; + -- Ignore responses. + wrep_ready <= '1'; + end Behavioral; diff --git a/hardware/interconnect/test/BusWriteSlaveMock.vhd b/hardware/interconnect/test/BusWriteSlaveMock.vhd index 023fc3286..fe617dc50 100644 --- a/hardware/interconnect/test/BusWriteSlaveMock.vhd +++ b/hardware/interconnect/test/BusWriteSlaveMock.vhd @@ -66,11 +66,15 @@ entity BusWriteSlaveMock is wreq_ready : out std_logic; wreq_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wreq_len : in std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wreq_last : in std_logic; wdat_valid : in std_logic; wdat_ready : out std_logic; wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - wdat_last : in std_logic + wdat_last : in std_logic; + wrep_valid : out std_logic; + wrep_ready : in std_logic; + wrep_ok : out std_logic ); end BusWriteSlaveMock; @@ -158,6 +162,20 @@ begin -- Stop accepting data wdat_ready <= '0'; + -- Send response + wrep_valid <= '1'; + wrep_ok <= '1'; + + -- Wait for response acknowledgement + loop + wait until rising_edge(clk); + exit state when reset = '1'; + exit when wrep_ready = '1'; + end loop; + + -- Stop sending response + wrep_valid <= '0'; + end loop; end process; From 810bed81094e1d89967ff951bcefadf381ffaece Mon Sep 17 00:00:00 2001 From: Jeroen van Straten Date: Wed, 6 Jan 2021 14:20:33 +0100 Subject: [PATCH 2/9] Add write response channel to buffer writers --- hardware/buffers/BufferWriter.vhd | 160 +++++++++++------- hardware/buffers/BufferWriterCmdGenBusReq.vhd | 55 +++++- hardware/buffers/Buffer_pkg.vhd | 9 +- .../test/bufferwriter/BufferWriter_tb.vhd | 37 ++-- hardware/interconnect/BusWriteBuffer.vhd | 10 +- hardware/interconnect/Interconnect_pkg.vhd | 5 +- 6 files changed, 182 insertions(+), 94 deletions(-) diff --git a/hardware/buffers/BufferWriter.vhd b/hardware/buffers/BufferWriter.vhd index 72a5a216f..3b50244ab 100644 --- a/hardware/buffers/BufferWriter.vhd +++ b/hardware/buffers/BufferWriter.vhd @@ -165,17 +165,19 @@ entity BufferWriter is bus_wreq_ready : in std_logic; bus_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic; -- Data channel bus_wdat_valid : out std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(BUS_STROBE_WIDTH-1 downto 0); - bus_wdat_last : out std_logic + bus_wdat_last : out std_logic; - - -- TODO in entity: - -- - status/error flags + -- Response channel + bus_wrep_valid : in std_logic; + bus_wrep_ready : out std_logic; + bus_wrep_ok : in std_logic ); end BufferWriter; @@ -191,12 +193,24 @@ architecture Behavioral of BufferWriter is signal writebuf_ready : std_logic; signal writebuf_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal writebuf_strobe : std_logic_vector(BUS_STROBE_WIDTH-1 downto 0); - signal writebuf_last : std_logic; - signal req_ready : std_logic; signal req_valid : std_logic; + signal req_ready : std_logic; signal req_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal req_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal req_last : std_logic; + signal req_valid_A : std_logic; + signal req_ready_A : std_logic; + signal req_valid_B : std_logic; + signal req_ready_B : std_logic; + + signal req_done_valid : std_logic; + signal req_done_ready : std_logic; + signal req_done_last : std_logic; + + signal rep_valid : std_logic; + signal rep_ready : std_logic; + signal rep_ok : std_logic; signal cmdIn_ready_pre : std_logic; signal cmdIn_ready_bus : std_logic; @@ -230,18 +244,6 @@ architecture Behavioral of BufferWriter is signal buffer_empty : std_logic; signal buffer_count : std_logic_vector(log2ceil(WRITE_BUFFER_DEPTH) downto 0); - signal int_bus_wreq_valid : std_logic; - signal int_bus_wreq_ready : std_logic; - signal int_bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - signal int_bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); - signal int_bus_wdat_valid : std_logic; - signal int_bus_wdat_ready : std_logic; - signal int_bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - signal int_bus_wdat_strobe : std_logic_vector(BUS_STROBE_WIDTH-1 downto 0); - signal int_bus_wdat_last : std_logic; - - signal last_in_cmd : std_logic; - signal unl_i_valid : std_logic; signal unl_i_ready : std_logic := '1'; signal unl_i_tag : std_logic_vector(CMD_TAG_WIDTH-1 downto 0); @@ -341,7 +343,6 @@ begin writebuf_strobe <= pre_strobe; writebuf_data <= pre_data; - writebuf_last <= pre_last; -- Generate signals for word_last to Write Buffer word_last <= pre_last; @@ -481,7 +482,47 @@ begin busReq_valid => req_valid, busReq_ready => req_ready, busReq_addr => req_addr, - busReq_len => req_len + busReq_len => req_len, + busReq_last => req_last + ); + + ----------------------------------------------------------------------------- + -- Request to response buffer and sync + ----------------------------------------------------------------------------- + -- We need the request last signal synchronized with the response channel + -- to determine when to unlock. + req_sync_inst: StreamSync + generic map ( + NUM_INPUTS => 1, + NUM_OUTPUTS => 2 + ) + port map ( + clk => kcd_clk, + reset => kcd_reset, + in_valid(0) => req_valid, + in_ready(0) => req_ready, + out_valid(0) => req_valid_A, + out_valid(1) => req_valid_B, + out_ready(0) => req_ready_A, + out_ready(1) => req_ready_B + ); + + req_to_rep_buffer_inst: StreamBuffer + generic map ( + MIN_DEPTH => 16, -- TODO: should probably be configurable + DATA_WIDTH => 1 + ) + port map ( + clk => kcd_clk, + reset => kcd_reset, + + in_valid => req_valid_B, + in_ready => req_ready_B, + in_data(0) => req_last, + + out_valid => req_done_valid, + out_ready => req_done_ready, + out_data(0) => req_done_last ); ----------------------------------------------------------------------------- @@ -505,37 +546,34 @@ begin empty => buffer_empty, count => buffer_count, - slv_wreq_valid => req_valid, - slv_wreq_ready => req_ready, + slv_wreq_valid => req_valid_A, + slv_wreq_ready => req_ready_A, slv_wreq_addr => req_addr, slv_wreq_len => req_len, + slv_wreq_last => req_last, slv_wdat_valid => writebuf_valid, slv_wdat_ready => writebuf_ready, slv_wdat_data => writebuf_data, slv_wdat_strobe => writebuf_strobe, - -- Last is actually the last word in the data stream of this command, so - -- pass it through using the control signal. Actual last will be - -- generated. - slv_wdat_ctrl(0) => writebuf_last, - slv_wdat_last => '0', - - mst_wreq_valid => int_bus_wreq_valid, - mst_wreq_ready => int_bus_wreq_ready, - mst_wreq_addr => int_bus_wreq_addr, - mst_wreq_len => int_bus_wreq_len, - mst_wdat_valid => int_bus_wdat_valid, - mst_wdat_ready => int_bus_wdat_ready, - mst_wdat_data => int_bus_wdat_data, - mst_wdat_strobe => int_bus_wdat_strobe, - mst_wdat_ctrl(0) => last_in_cmd, - mst_wdat_last => int_bus_wdat_last + slv_wrep_valid => rep_valid, + slv_wrep_ready => rep_ready, + slv_wrep_ok => rep_ok, + + mst_wreq_valid => bus_wreq_valid, + mst_wreq_ready => bus_wreq_ready, + mst_wreq_addr => bus_wreq_addr, + mst_wreq_len => bus_wreq_len, + mst_wreq_last => bus_wreq_last, + mst_wdat_valid => bus_wdat_valid, + mst_wdat_ready => bus_wdat_ready, + mst_wdat_data => bus_wdat_data, + mst_wdat_strobe => bus_wdat_strobe, + mst_wdat_last => bus_wdat_last, + mst_wrep_valid => bus_wrep_valid, + mst_wrep_ready => bus_wrep_ready, + mst_wrep_ok => bus_wrep_ok ); - int_bus_wreq_ready <= bus_wreq_ready; - bus_wreq_valid <= int_bus_wreq_valid; - bus_wreq_addr <= int_bus_wreq_addr; - bus_wreq_len <= int_bus_wreq_len; - -- Input buffer for the unlock stream to prevent blocking the command stream unlock_input_buffer_inst: StreamBuffer generic map ( @@ -559,38 +597,31 @@ begin -- both the data and command stream. unlock_bus_sync_inst: StreamSync generic map ( - NUM_INPUTS => 2, - NUM_OUTPUTS => 2 + NUM_INPUTS => 3, + NUM_OUTPUTS => 1 ) port map ( clk => kcd_clk, reset => kcd_reset, - in_valid(0) => int_bus_wdat_valid, - in_valid(1) => unl_i_valid, - - in_advance(0) => '1', - in_advance(1) => last_in_cmd, + in_valid(2) => req_done_valid, + in_valid(1) => rep_valid, + in_valid(0) => unl_i_valid, - in_ready(0) => int_bus_wdat_ready, - in_ready(1) => unl_i_ready, + in_ready(2) => req_done_ready, + in_ready(1) => rep_ready, + in_ready(0) => unl_i_ready, - out_valid(0) => bus_wdat_valid, - out_valid(1) => unl_o_valid, + in_advance(2) => '1', + in_advance(1) => '1', + in_advance(0) => req_done_last, - out_ready(0) => bus_wdat_ready, - out_ready(1) => unl_o_ready, - - out_enable(0) => '1', - out_enable(1) => last_in_cmd + out_valid(0) => unl_o_valid, + out_ready(0) => unl_o_ready, + out_enable(0) => req_done_last ); - -- Connect to output - bus_wdat_data <= int_bus_wdat_data; - bus_wdat_strobe <= int_bus_wdat_strobe; - bus_wdat_last <= int_bus_wdat_last; - -- Connect the input buffer to the output buffer. unl_o_tag <= unl_i_tag; @@ -604,7 +635,6 @@ begin clk => kcd_clk, reset => kcd_reset, - -- Only valid when last_in_cmd is high in_valid => unl_o_valid, in_ready => unl_o_ready, in_data => unl_o_tag, diff --git a/hardware/buffers/BufferWriterCmdGenBusReq.vhd b/hardware/buffers/BufferWriterCmdGenBusReq.vhd index bfea5662d..af1e9cf46 100644 --- a/hardware/buffers/BufferWriterCmdGenBusReq.vhd +++ b/hardware/buffers/BufferWriterCmdGenBusReq.vhd @@ -113,7 +113,8 @@ entity BufferWriterCmdGenBusReq is busReq_valid : out std_logic; busReq_ready : in std_logic; busReq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - busReq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0) + busReq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + busReq_last : out std_logic ); end BufferWriterCmdGenBusReq; @@ -149,6 +150,7 @@ architecture rtl of BufferWriterCmdGenBusReq is type master_record is record addr : unsigned(BUS_ADDR_WIDTH-1 downto 0); len : unsigned(BUS_LEN_WIDTH-1 downto 0); + last : std_logic; valid : std_logic; end record; @@ -301,6 +303,7 @@ begin vo.master.addr := byte_address; vo.master.len := STEP_LEN; vo.master.valid := '0'; + vo.master.last := '0'; vo.cnt_ctrl.step_sub := '0'; vo.cnt_ctrl.max_sub := '0'; vo.cnt_ctrl.reset := '0'; @@ -354,22 +357,32 @@ begin -- Make bus request valid vo.master.valid := '1'; + -- Set the last flag for the bus request if we've seen the last data + -- word and only a single step remains (after the last transfer has + -- been accumulated in the counter) + if vr.last = '1' and counter.step = 1 then + vo.master.last := '1'; + end if; + -- Invalidate if we've reached the alignment boundary if isAligned(byte_address, log2floor(BYTE_ALIGN)) then vo.master.valid := '0'; vr.state := MAX; end if; + -- Check if a last step is at the input of the steps counter stream + if steps_last = '1' and steps_valid = '1' then + vr.last := '1'; + end if; + -- Invalidate if there is no burst step in the FIFO if counter.step = 0 then vo.master.valid := '0'; end if; - -- Invalidate if this is the last word; the POST_STEP state should - -- handle this - if steps_last = '1' and steps_valid = '1' then - vo.master.valid := '0'; - vr.last := '1'; + -- Go to the POST_STEP state if this is the last word of this command + -- and there is no outstanding bus request + if vo.master.valid = '0' and vr.last = '1' then vr.state := POST_STEP; end if; @@ -377,6 +390,10 @@ begin if busReq_ready = '1' and vo.master.valid = '1' then vo.cnt_ctrl.step_sub := '1'; vr.index.current := vr.index.current + ELEMS_PER_STEP; + + if vr.last = '1' then + vr.state := POST_STEP; + end if; end if; ------------------------------------------------------------------------- @@ -393,12 +410,19 @@ begin -- Make bus request valid vo.master.valid := '1'; + -- Set the last flag for the bus request if we've seen the last data + -- word and exactly a max burst remains (after the last transfer has + -- been accumulated in the counter) + if vr.last = '1' and counter.step = MAX_STEPS then + vo.master.last := '1'; + end if; + -- Check if a last step is at the input of the steps counter stream if steps_last = '1' and steps_valid = '1' then vr.last := '1'; end if; - -- Invalidate if there is no max burst step in the FIFO + -- Invalidate if there is no max burst step in the FIFO if counter.step < MAX_STEPS then vo.master.valid := '0'; end if; @@ -438,6 +462,20 @@ begin -- Make bus request valid vo.master.valid := '1'; + -- Set the last flag for the bus request if we're sending the last + -- step + if vr.last = '1' then + if counter.step < MAX_STEPS then + if counter.step = 1 then + vo.master.last := '1'; + end if; + else + if counter.step = MAX_STEPS then + vo.master.last := '1'; + end if; + end if; + end if; + -- Stop when all steps have been requested. if counter.step = 0 then vo.master.valid := '0'; @@ -463,12 +501,13 @@ begin busReq_addr <= slv(vo.master.addr); busReq_len <= slv(vo.master.len); + busReq_last <= vo.master.last; busReq_valid <= vo.master.valid; cnt_ctrl <= vo.cnt_ctrl; int_steps_ready <= vo.steps_ready; end process; - + steps_ready <= int_steps_ready; end rtl; diff --git a/hardware/buffers/Buffer_pkg.vhd b/hardware/buffers/Buffer_pkg.vhd index 44f1bdffe..74cb1aec9 100644 --- a/hardware/buffers/Buffer_pkg.vhd +++ b/hardware/buffers/Buffer_pkg.vhd @@ -338,11 +338,15 @@ package Buffer_pkg is bus_wreq_ready : in std_logic; bus_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic; bus_wdat_valid : out std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(BUS_STROBE_WIDTH-1 downto 0); - bus_wdat_last : out std_logic + bus_wdat_last : out std_logic; + bus_wrep_valid : in std_logic; + bus_wrep_ready : out std_logic; + bus_wrep_ok : in std_logic ); end component; @@ -462,7 +466,8 @@ package Buffer_pkg is busReq_valid : out std_logic; busReq_ready : in std_logic; busReq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - busReq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0) + busReq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + busReq_last : out std_logic ); end component; diff --git a/hardware/buffers/test/bufferwriter/BufferWriter_tb.vhd b/hardware/buffers/test/bufferwriter/BufferWriter_tb.vhd index 117f30660..9e4197851 100644 --- a/hardware/buffers/test/bufferwriter/BufferWriter_tb.vhd +++ b/hardware/buffers/test/bufferwriter/BufferWriter_tb.vhd @@ -110,11 +110,15 @@ architecture tb of BufferWriter_tb is signal bus_wreq_ready : std_logic; signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bus_wreq_last : std_logic; signal bus_wdat_valid : std_logic; signal bus_wdat_ready : std_logic; signal bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bus_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal bus_wdat_last : std_logic; + signal bus_wrep_valid : std_logic; + signal bus_wrep_ready : std_logic; + signal bus_wrep_ok : std_logic; signal cycle : unsigned(63 downto 0) := (others => '0'); @@ -467,17 +471,15 @@ begin variable elem_written : unsigned(ELEMENT_WIDTH-1 downto 0); variable elem_expected : unsigned(ELEMENT_WIDTH-1 downto 0); begin - bus_wreq_ready <= '1'; - bus_wdat_ready <= '0'; + bus_wreq_ready <= '1'; + bus_wdat_ready <= '0'; + bus_wrep_valid <= '0'; loop - -- Exit when all writes are done - if write_done then - exit; - end if; -- Wait for a bus request - wait until rising_edge(kcd_clk) and (bus_wreq_ready = '1' and bus_wreq_valid = '1'); - bus_wreq_ready <= '0'; - bus_wdat_ready <= '1'; + wait until rising_edge(kcd_clk) and (sim_done or (bus_wreq_ready = '1' and bus_wreq_valid = '1')); + exit when sim_done; + bus_wreq_ready <= '0'; + bus_wdat_ready <= '1'; -- Remember the burst length len := unsigned(bus_wreq_len); @@ -550,9 +552,16 @@ begin -- Increase current index index := index + BUS_DATA_WIDTH / ELEMENT_WIDTH; end loop; + bus_wdat_ready <= '0'; + + -- Send response + bus_wrep_valid <= '1'; + bus_wrep_ok <= '1'; + wait until rising_edge(kcd_clk) and (bus_wrep_ready = '1'); + bus_wrep_valid <= '0'; + -- Start accepting new requests - bus_wreq_ready <= '1'; - bus_wdat_ready <= '0'; + bus_wreq_ready <= '1'; end loop; wait; end process; @@ -640,11 +649,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, - bus_wdat_last => bus_wdat_last + bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok ); end architecture; diff --git a/hardware/interconnect/BusWriteBuffer.vhd b/hardware/interconnect/BusWriteBuffer.vhd index 8d5cc2f62..41bb24ccb 100644 --- a/hardware/interconnect/BusWriteBuffer.vhd +++ b/hardware/interconnect/BusWriteBuffer.vhd @@ -107,7 +107,7 @@ entity BusWriteBuffer is slv_wdat_ready : out std_logic; slv_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); slv_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - slv_wdat_last : in std_logic; + slv_wdat_last : in std_logic := '0'; slv_wdat_ctrl : in std_logic_vector(CTRL_WIDTH-1 downto 0) := (others => 'U'); slv_wrep_valid : out std_logic; @@ -164,16 +164,16 @@ architecture Behavioral of BusWriteBuffer is signal s_mst_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal s_mst_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); signal s_mst_wreq_last : std_logic; - signal s_mst_wreq_all : std_logic_vector(RSI(2)-1 downto 0); - signal mst_wreq_all : std_logic_vector(RSI(2)-1 downto 0); + signal s_mst_wreq_all : std_logic_vector(RSI(3)-1 downto 0); + signal mst_wreq_all : std_logic_vector(RSI(3)-1 downto 0); signal s_slv_wreq_valid : std_logic; signal s_slv_wreq_ready : std_logic; signal s_slv_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal s_slv_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); signal s_slv_wreq_last : std_logic; - signal s_slv_wreq_all : std_logic_vector(RSI(2)-1 downto 0); - signal slv_wreq_all : std_logic_vector(RSI(2)-1 downto 0); + signal s_slv_wreq_all : std_logic_vector(RSI(3)-1 downto 0); + signal slv_wreq_all : std_logic_vector(RSI(3)-1 downto 0); signal s_slv_wdat_valid : std_logic; signal s_slv_wdat_ready : std_logic; diff --git a/hardware/interconnect/Interconnect_pkg.vhd b/hardware/interconnect/Interconnect_pkg.vhd index c5199f9d9..22abe8b82 100644 --- a/hardware/interconnect/Interconnect_pkg.vhd +++ b/hardware/interconnect/Interconnect_pkg.vhd @@ -181,6 +181,7 @@ package Interconnect_pkg is reset : in std_logic; full : out std_logic; empty : out std_logic; + error : out std_logic; count : out std_logic_vector(log2ceil(FIFO_DEPTH) downto 0); slv_wreq_valid : in std_logic; @@ -192,8 +193,8 @@ package Interconnect_pkg is slv_wdat_ready : out std_logic; slv_wdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); slv_wdat_strobe : in std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); + slv_wdat_last : in std_logic := '0'; slv_wdat_ctrl : in std_logic_vector(CTRL_WIDTH-1 downto 0) := (others => 'U'); - slv_wdat_last : in std_logic; slv_wrep_valid : out std_logic; slv_wrep_ready : in std_logic; slv_wrep_ok : out std_logic; @@ -207,8 +208,8 @@ package Interconnect_pkg is mst_wdat_ready : in std_logic; mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - mst_wdat_ctrl : out std_logic_vector(CTRL_WIDTH-1 downto 0); mst_wdat_last : out std_logic; + mst_wdat_ctrl : out std_logic_vector(CTRL_WIDTH-1 downto 0); mst_wrep_valid : in std_logic; mst_wrep_ready : out std_logic; mst_wrep_ok : in std_logic From 882847d2c639ef70e47c5ecfd3f5866a9190588f Mon Sep 17 00:00:00 2001 From: Jeroen van Straten Date: Wed, 6 Jan 2021 15:03:01 +0100 Subject: [PATCH 3/9] Add write response channel to array writers --- hardware/arrays/ArrayWriter.vhd | 8 +++++ hardware/arrays/ArrayWriterArb.vhd | 26 +++++++++++++++- hardware/arrays/ArrayWriterLevel.vhd | 28 +++++++++++++++++ hardware/arrays/ArrayWriterListPrim.vhd | 19 ++++++++++-- hardware/arrays/Array_pkg.vhd | 16 ++++++++++ .../test/arraywriter/listprim8epc4_tc.vhd | 29 +++++++++++++++++- .../arrays/test/arraywriter/prim32_epc_tc.vhd | 30 ++++++++----------- .../arrays/test/arraywriter/prim32_tc.vhd | 30 ++++++++----------- hardware/interconnect/BusWriteArbiterVec.vhd | 7 ++++- 9 files changed, 154 insertions(+), 39 deletions(-) diff --git a/hardware/arrays/ArrayWriter.vhd b/hardware/arrays/ArrayWriter.vhd index 216df4995..9b89c3655 100644 --- a/hardware/arrays/ArrayWriter.vhd +++ b/hardware/arrays/ArrayWriter.vhd @@ -121,11 +121,15 @@ entity ArrayWriter is bus_wreq_ready : in std_logic; bus_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic; bus_wdat_valid : out std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); bus_wdat_last : out std_logic; + bus_wrep_valid : in std_logic; + bus_wrep_ready : out std_logic; + bus_wrep_ok : in std_logic; --------------------------------------------------------------------------- -- User streams @@ -191,11 +195,15 @@ begin bus_wreq_ready(0) => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last(0) => bus_wreq_last, bus_wdat_valid(0) => bus_wdat_valid, bus_wdat_ready(0) => bus_wdat_ready, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_data => bus_wdat_data, bus_wdat_last(0) => bus_wdat_last, + bus_wrep_valid(0) => bus_wrep_valid, + bus_wrep_ready(0) => bus_wrep_ready, + bus_wrep_ok(0) => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, diff --git a/hardware/arrays/ArrayWriterArb.vhd b/hardware/arrays/ArrayWriterArb.vhd index 3cf77b976..a1c768a47 100644 --- a/hardware/arrays/ArrayWriterArb.vhd +++ b/hardware/arrays/ArrayWriterArb.vhd @@ -115,11 +115,15 @@ entity ArrayWriterArb is bus_wreq_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wreq_addr : out std_logic_vector(arcfg_busCount(CFG)*BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(arcfg_busCount(CFG)*BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_valid : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_data : out std_logic_vector(arcfg_busCount(CFG)*BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(arcfg_busCount(CFG)*BUS_DATA_WIDTH/8-1 downto 0); bus_wdat_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_valid : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ready : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ok : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); --------------------------------------------------------------------------- -- User streams @@ -162,11 +166,15 @@ architecture Behavioral of ArrayWriterArb is signal a_bus_wreq_ready : std_logic_vector(A_BUS_COUNT-1 downto 0); signal a_bus_wreq_addr : std_logic_vector(A_BUS_COUNT*BUS_ADDR_WIDTH-1 downto 0); signal a_bus_wreq_len : std_logic_vector(A_BUS_COUNT*BUS_LEN_WIDTH-1 downto 0); + signal a_bus_wreq_last : std_logic_vector(A_BUS_COUNT-1 downto 0); signal a_bus_wdat_valid : std_logic_vector(A_BUS_COUNT-1 downto 0); signal a_bus_wdat_ready : std_logic_vector(A_BUS_COUNT-1 downto 0); signal a_bus_wdat_data : std_logic_vector(A_BUS_COUNT*BUS_DATA_WIDTH-1 downto 0); signal a_bus_wdat_strobe : std_logic_vector(A_BUS_COUNT*BUS_DATA_WIDTH/8-1 downto 0); signal a_bus_wdat_last : std_logic_vector(A_BUS_COUNT-1 downto 0); + signal a_bus_wrep_valid : std_logic_vector(A_BUS_COUNT-1 downto 0); + signal a_bus_wrep_ready : std_logic_vector(A_BUS_COUNT-1 downto 0); + signal a_bus_wrep_ok : std_logic_vector(A_BUS_COUNT-1 downto 0); signal a_in_valid : std_logic_vector(A_USER_COUNT-1 downto 0); signal a_in_ready : std_logic_vector(A_USER_COUNT-1 downto 0); @@ -285,22 +293,30 @@ begin bsv_wreq_ready => a_bus_wreq_ready, bsv_wreq_addr => a_bus_wreq_addr, bsv_wreq_len => a_bus_wreq_len, + bsv_wreq_last => a_bus_wreq_last, bsv_wdat_valid => a_bus_wdat_valid, bsv_wdat_ready => a_bus_wdat_ready, bsv_wdat_data => a_bus_wdat_data, bsv_wdat_strobe => a_bus_wdat_strobe, bsv_wdat_last => a_bus_wdat_last, + bsv_wrep_valid => a_bus_wrep_valid, + bsv_wrep_ready => a_bus_wrep_ready, + bsv_wrep_ok => a_bus_wrep_ok, -- Master port (output) mst_wreq_valid => bus_wreq_valid(0), mst_wreq_ready => bus_wreq_ready(0), mst_wreq_addr => bus_wreq_addr, mst_wreq_len => bus_wreq_len, + mst_wreq_last => bus_wreq_last(0), mst_wdat_valid => bus_wdat_valid(0), mst_wdat_ready => bus_wdat_ready(0), mst_wdat_data => bus_wdat_data, mst_wdat_strobe => bus_wdat_strobe, - mst_wdat_last => bus_wdat_last(0) + mst_wdat_last => bus_wdat_last(0), + mst_wrep_valid => bus_wrep_valid(0), + mst_wrep_ready => bus_wrep_ready(0), + mst_wrep_ok => bus_wrep_ok(0) ); end generate; no_arb_gen: if A_BUS_COUNT = 1 generate @@ -311,11 +327,15 @@ begin a_bus_wreq_ready <= bus_wreq_ready; bus_wreq_addr <= a_bus_wreq_addr; bus_wreq_len <= a_bus_wreq_len; + bus_wreq_last <= a_bus_wreq_last; bus_wdat_valid <= a_bus_wdat_valid; a_bus_wdat_ready <= bus_wdat_ready; bus_wdat_data <= a_bus_wdat_data; bus_wdat_strobe <= a_bus_wdat_strobe; bus_wdat_last <= a_bus_wdat_last; + a_bus_wrep_valid <= bus_wrep_valid; + bus_wrep_ready <= a_bus_wrep_ready; + a_bus_wrep_ok <= bus_wrep_ok; end generate; -- Optional user stream slices. @@ -393,11 +413,15 @@ begin bus_wreq_ready => a_bus_wreq_ready, bus_wreq_addr => a_bus_wreq_addr, bus_wreq_len => a_bus_wreq_len, + bus_wreq_last => a_bus_wreq_last, bus_wdat_valid => a_bus_wdat_valid, bus_wdat_ready => a_bus_wdat_ready, bus_wdat_data => a_bus_wdat_data, bus_wdat_strobe => a_bus_wdat_strobe, bus_wdat_last => a_bus_wdat_last, + bus_wrep_valid => a_bus_wrep_valid, + bus_wrep_ready => a_bus_wrep_ready, + bus_wrep_ok => a_bus_wrep_ok, in_valid => a_in_valid, in_ready => a_in_ready, diff --git a/hardware/arrays/ArrayWriterLevel.vhd b/hardware/arrays/ArrayWriterLevel.vhd index 424a07fa3..207ae0533 100644 --- a/hardware/arrays/ArrayWriterLevel.vhd +++ b/hardware/arrays/ArrayWriterLevel.vhd @@ -114,11 +114,15 @@ entity ArrayWriterLevel is bus_wreq_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wreq_addr : out std_logic_vector(arcfg_busCount(CFG)*BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(arcfg_busCount(CFG)*BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_valid : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_data : out std_logic_vector(arcfg_busCount(CFG)*BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(arcfg_busCount(CFG)*BUS_DATA_WIDTH/8-1 downto 0); bus_wdat_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_valid : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ready : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ok : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); --------------------------------------------------------------------------- -- User streams @@ -201,11 +205,15 @@ begin bus_wreq_ready => bus_wreq_ready(0), bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last(0), bus_wdat_valid => bus_wdat_valid(0), bus_wdat_ready => bus_wdat_ready(0), bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last(0), + bus_wrep_valid => bus_wrep_valid(0), + bus_wrep_ready => bus_wrep_ready(0), + bus_wrep_ok => bus_wrep_ok(0), in_valid => in_valid(0), in_ready => in_ready(0), @@ -253,11 +261,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, @@ -322,11 +334,15 @@ begin -- bus_wreq_ready => bus_wreq_ready, -- bus_wreq_addr => bus_wreq_addr, -- bus_wreq_len => bus_wreq_len, + -- bus_wreq_last => bus_wreq_last, -- bus_wdat_valid => bus_wdat_valid, -- bus_wdat_ready => bus_wdat_ready, -- bus_wdat_data => bus_wdat_data, -- bus_wdat_strobe => bus_wdat_strobe, -- bus_wdat_last => bus_wdat_last, + -- bus_wrep_valid => bus_wrep_valid, + -- bus_wrep_ready => bus_wrep_ready, + -- bus_wrep_ok => bus_wrep_ok, -- -- in_valid => in_valid, -- in_ready => in_ready, @@ -397,11 +413,15 @@ begin -- bus_wreq_ready => bus_wreq_ready, -- bus_wreq_addr => bus_wreq_addr, -- bus_wreq_len => bus_wreq_len, + -- bus_wreq_last => bus_wreq_last, -- bus_wdat_valid => bus_wdat_valid, -- bus_wdat_ready => bus_wdat_ready, -- bus_wdat_data => bus_wdat_data, -- bus_wdat_strobe => bus_wdat_strobe, -- bus_wdat_last => bus_wdat_last, + -- bus_wrep_valid => bus_wrep_valid, + -- bus_wrep_ready => bus_wrep_ready, + -- bus_wrep_ok => bus_wrep_ok, -- -- in_valid => in_valid, -- in_ready => in_ready, @@ -455,11 +475,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, @@ -508,11 +532,15 @@ begin -- bus_wreq_ready => bus_wreq_ready, -- bus_wreq_addr => bus_wreq_addr, -- bus_wreq_len => bus_wreq_len, + -- bus_wreq_last => bus_wreq_last, -- bus_wdat_valid => bus_wdat_valid, -- bus_wdat_ready => bus_wdat_ready, -- bus_wdat_data => bus_wdat_data, -- bus_wdat_strobe => bus_wdat_strobe, -- bus_wdat_last => bus_wdat_last, + -- bus_wrep_valid => bus_wrep_valid, + -- bus_wrep_ready => bus_wrep_ready, + -- bus_wrep_ok => bus_wrep_ok, -- -- in_valid => in_valid, -- in_ready => in_ready, diff --git a/hardware/arrays/ArrayWriterListPrim.vhd b/hardware/arrays/ArrayWriterListPrim.vhd index e1c40c913..a290d5b37 100644 --- a/hardware/arrays/ArrayWriterListPrim.vhd +++ b/hardware/arrays/ArrayWriterListPrim.vhd @@ -115,6 +115,7 @@ entity ArrayWriterListPrim is bus_wreq_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wreq_addr : out std_logic_vector(arcfg_busCount(CFG)*BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(arcfg_busCount(CFG)*BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_valid : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); bus_wdat_ready : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); @@ -122,6 +123,10 @@ entity ArrayWriterListPrim is bus_wdat_strobe : out std_logic_vector(arcfg_busCount(CFG)*BUS_DATA_WIDTH/8-1 downto 0); bus_wdat_last : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_valid : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ready : out std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + bus_wrep_ok : in std_logic_vector(arcfg_busCount(CFG)-1 downto 0); + --------------------------------------------------------------------------- -- User streams --------------------------------------------------------------------------- @@ -340,12 +345,17 @@ begin bus_wreq_ready => bus_wreq_ready(0), bus_wreq_addr => bus_wreq_addr(BUS_ADDR_WIDTH-1 downto 0), bus_wreq_len => bus_wreq_len(BUS_LEN_WIDTH-1 downto 0), + bus_wreq_last => bus_wreq_last(0), bus_wdat_valid => bus_wdat_valid(0), bus_wdat_ready => bus_wdat_ready(0), bus_wdat_data => bus_wdat_data(BUS_DATA_WIDTH-1 downto 0), bus_wdat_strobe => bus_wdat_strobe(BUS_DATA_WIDTH/8-1 downto 0), - bus_wdat_last => bus_wdat_last(0) + bus_wdat_last => bus_wdat_last(0), + + bus_wrep_valid => bus_wrep_valid(0), + bus_wrep_ready => bus_wrep_ready(0), + bus_wrep_ok => bus_wrep_ok(0) ); -- Instantiate primitive element buffer reader. @@ -395,12 +405,17 @@ begin bus_wreq_ready => bus_wreq_ready(1), bus_wreq_addr => bus_wreq_addr(2*BUS_ADDR_WIDTH-1 downto BUS_ADDR_WIDTH), bus_wreq_len => bus_wreq_len(2*BUS_LEN_WIDTH-1 downto BUS_LEN_WIDTH), + bus_wreq_last => bus_wreq_len(1), bus_wdat_valid => bus_wdat_valid(1), bus_wdat_ready => bus_wdat_ready(1), bus_wdat_data => bus_wdat_data(2*BUS_DATA_WIDTH-1 downto BUS_DATA_WIDTH), bus_wdat_strobe => bus_wdat_strobe(2*BUS_DATA_WIDTH/8-1 downto BUS_DATA_WIDTH/8), - bus_wdat_last => bus_wdat_last(1) + bus_wdat_last => bus_wdat_last(1), + + bus_wrep_valid => bus_wrep_valid(1), + bus_wrep_ready => bus_wrep_ready(1), + bus_wrep_ok => bus_wrep_ok(1) ); end Behavioral; diff --git a/hardware/arrays/Array_pkg.vhd b/hardware/arrays/Array_pkg.vhd index 738b128b6..8719062e4 100644 --- a/hardware/arrays/Array_pkg.vhd +++ b/hardware/arrays/Array_pkg.vhd @@ -54,11 +54,15 @@ package Array_pkg is bus_wreq_ready : in std_logic; bus_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); bus_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + bus_wreq_last : out std_logic; bus_wdat_valid : out std_logic; bus_wdat_ready : in std_logic; bus_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); bus_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); bus_wdat_last : out std_logic; + bus_wrep_valid : in std_logic; + bus_wrep_ready : out std_logic; + bus_wrep_ok : in std_logic; in_valid : in std_logic_vector(arcfg_userCount(CFG)-1 downto 0); in_ready : out std_logic_vector(arcfg_userCount(CFG)-1 downto 0); in_last : in std_logic_vector(arcfg_userCount(CFG)-1 downto 0); @@ -97,11 +101,15 @@ package Array_pkg is bus_wreq_ready : in std_logic_vector; bus_wreq_addr : out std_logic_vector; bus_wreq_len : out std_logic_vector; + bus_wreq_last : out std_logic_vector; bus_wdat_valid : out std_logic_vector; bus_wdat_ready : in std_logic_vector; bus_wdat_data : out std_logic_vector; bus_wdat_strobe : out std_logic_vector; bus_wdat_last : out std_logic_vector; + bus_wrep_valid : in std_logic_vector; + bus_wrep_ready : out std_logic_vector; + bus_wrep_ok : in std_logic_vector; in_valid : in std_logic_vector; in_ready : out std_logic_vector; in_last : in std_logic_vector; @@ -140,11 +148,15 @@ package Array_pkg is bus_wreq_ready : in std_logic_vector; bus_wreq_addr : out std_logic_vector; bus_wreq_len : out std_logic_vector; + bus_wreq_last : out std_logic_vector; bus_wdat_valid : out std_logic_vector; bus_wdat_ready : in std_logic_vector; bus_wdat_data : out std_logic_vector; bus_wdat_strobe : out std_logic_vector; bus_wdat_last : out std_logic_vector; + bus_wrep_valid : in std_logic_vector; + bus_wrep_ready : out std_logic_vector; + bus_wrep_ok : in std_logic_vector; in_valid : in std_logic_vector; in_ready : out std_logic_vector; in_last : in std_logic_vector; @@ -183,11 +195,15 @@ package Array_pkg is bus_wreq_ready : in std_logic_vector; bus_wreq_addr : out std_logic_vector; bus_wreq_len : out std_logic_vector; + bus_wreq_last : out std_logic_vector; bus_wdat_valid : out std_logic_vector; bus_wdat_ready : in std_logic_vector; bus_wdat_data : out std_logic_vector; bus_wdat_strobe : out std_logic_vector; bus_wdat_last : out std_logic_vector; + bus_wrep_valid : in std_logic_vector; + bus_wrep_ready : out std_logic_vector; + bus_wrep_ok : in std_logic_vector; in_valid : in std_logic_vector; in_ready : out std_logic_vector; in_last : in std_logic_vector; diff --git a/hardware/arrays/test/arraywriter/listprim8epc4_tc.vhd b/hardware/arrays/test/arraywriter/listprim8epc4_tc.vhd index ab9910873..d04870fb2 100644 --- a/hardware/arrays/test/arraywriter/listprim8epc4_tc.vhd +++ b/hardware/arrays/test/arraywriter/listprim8epc4_tc.vhd @@ -76,11 +76,15 @@ architecture tb of listprim8epc4_tc is signal bus_wreq_ready : std_logic; signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bus_wreq_last : std_logic; signal bus_wdat_valid : std_logic; signal bus_wdat_ready : std_logic; signal bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bus_wdat_strobe : std_logic_vector(BUS_STROBE_WIDTH-1 downto 0); signal bus_wdat_last : std_logic; + signal bus_wrep_valid : std_logic; + signal bus_wrep_ready : std_logic; + signal bus_wrep_ok : std_logic; signal in_valid : std_logic_vector(arcfg_userCount(CFG)-1 downto 0); signal in_ready : std_logic_vector(arcfg_userCount(CFG)-1 downto 0); @@ -364,9 +368,28 @@ begin end process; - bus_wreq_ready <= '1'; bus_wdat_ready <= '1'; + req_to_rep_buffer_inst: StreamBuffer + generic map ( + MIN_DEPTH => 2, + DATA_WIDTH => 1 + ) + port map ( + clk => kcd_clk, + reset => kcd_reset, + + in_valid => bus_wreq_valid, + in_ready => bus_wreq_ready, + in_data => "0", + + out_valid => bus_wrep_valid, + out_ready => bus_wrep_ready, + out_data => open + ); + + bus_wrep_ok <= '1'; + uut : ArrayWriter generic map ( BUS_ADDR_WIDTH => BUS_ADDR_WIDTH, @@ -397,11 +420,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, in_last => in_last, diff --git a/hardware/arrays/test/arraywriter/prim32_epc_tc.vhd b/hardware/arrays/test/arraywriter/prim32_epc_tc.vhd index 31c5f6c3d..7b055b6e8 100644 --- a/hardware/arrays/test/arraywriter/prim32_epc_tc.vhd +++ b/hardware/arrays/test/arraywriter/prim32_epc_tc.vhd @@ -69,11 +69,15 @@ architecture tb of prim32_epc_tc is signal bus_wreq_ready : std_logic; signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bus_wreq_last : std_logic; signal bus_wdat_valid : std_logic; signal bus_wdat_ready : std_logic; signal bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bus_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal bus_wdat_last : std_logic; + signal bus_wrep_valid : std_logic; + signal bus_wrep_ready : std_logic; + signal bus_wrep_ok : std_logic; signal in_valid : std_logic_vector( 1-1 downto 0); signal in_ready : std_logic_vector( 1-1 downto 0); @@ -89,22 +93,6 @@ architecture tb of prim32_epc_tc is signal num_last : std_logic; signal num_dvalid : std_logic; - --------------------------------------------------------------------------- - -- Master bus Result - --------------------------------------------------------------------------- - -- Write request channel - signal bus_result_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - signal bus_result_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); - signal bus_result_wreq_valid : std_logic; - signal bus_result_wreq_ready : std_logic; - - -- Write response channel - signal bus_result_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - signal bus_result_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - signal bus_result_wdat_last : std_logic; - signal bus_result_wdat_valid : std_logic; - signal bus_result_wdat_ready : std_logic; - -- Other stuff signal clock_stop : boolean := false; signal num_done : boolean := false; @@ -285,11 +273,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, - bus_wdat_last => bus_wdat_last + bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok ); in_data_flat <= in_count & in_data; @@ -324,11 +316,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, in_last => in_last, diff --git a/hardware/arrays/test/arraywriter/prim32_tc.vhd b/hardware/arrays/test/arraywriter/prim32_tc.vhd index bc9445e3b..6ec84e2ec 100644 --- a/hardware/arrays/test/arraywriter/prim32_tc.vhd +++ b/hardware/arrays/test/arraywriter/prim32_tc.vhd @@ -69,11 +69,15 @@ architecture tb of prim32_tc is signal bus_wreq_ready : std_logic; signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + signal bus_wreq_last : std_logic; signal bus_wdat_valid : std_logic; signal bus_wdat_ready : std_logic; signal bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal bus_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); signal bus_wdat_last : std_logic; + signal bus_wrep_valid : std_logic; + signal bus_wrep_ready : std_logic; + signal bus_wrep_ok : std_logic; signal in_valid : std_logic_vector(arcfg_userCount(CFG)-1 downto 0); signal in_ready : std_logic_vector(arcfg_userCount(CFG)-1 downto 0); @@ -87,22 +91,6 @@ architecture tb of prim32_tc is signal num_last : std_logic; signal num_dvalid : std_logic; - --------------------------------------------------------------------------- - -- Master bus Result - --------------------------------------------------------------------------- - -- Write request channel - signal bus_result_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - signal bus_result_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); - signal bus_result_wreq_valid : std_logic; - signal bus_result_wreq_ready : std_logic; - - -- Write response channel - signal bus_result_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - signal bus_result_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); -- TODO Laurens: "/8"? - signal bus_result_wdat_last : std_logic; - signal bus_result_wdat_valid : std_logic; - signal bus_result_wdat_ready : std_logic; - -- Other stuff signal clock_stop : boolean := false; signal num_done : boolean := false; @@ -281,11 +269,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, - bus_wdat_last => bus_wdat_last + bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok ); uut : ArrayWriter @@ -318,11 +310,15 @@ begin bus_wreq_ready => bus_wreq_ready, bus_wreq_addr => bus_wreq_addr, bus_wreq_len => bus_wreq_len, + bus_wreq_last => bus_wreq_last, bus_wdat_valid => bus_wdat_valid, bus_wdat_ready => bus_wdat_ready, bus_wdat_data => bus_wdat_data, bus_wdat_strobe => bus_wdat_strobe, bus_wdat_last => bus_wdat_last, + bus_wrep_valid => bus_wrep_valid, + bus_wrep_ready => bus_wrep_ready, + bus_wrep_ok => bus_wrep_ok, in_valid => in_valid, in_ready => in_ready, in_last => in_last, diff --git a/hardware/interconnect/BusWriteArbiterVec.vhd b/hardware/interconnect/BusWriteArbiterVec.vhd index bd226ee20..5949fe311 100644 --- a/hardware/interconnect/BusWriteArbiterVec.vhd +++ b/hardware/interconnect/BusWriteArbiterVec.vhd @@ -128,6 +128,7 @@ architecture Behavioral of BusWriteArbiterVec is -- Bus request channel serialization indices. constant BQI : nat_array := cumulative(( + 2 => 1, 1 => BUS_ADDR_WIDTH, 0 => BUS_LEN_WIDTH )); @@ -209,6 +210,7 @@ architecture Behavioral of BusWriteArbiterVec is -- Arbiter output stream handshake. signal arb_out_valid : std_logic; signal arb_out_ready : std_logic; + signal arb_out_index : std_logic_vector(INDEX_WIDTH-1 downto 0); -- Index stream stage A (between sync and buffer for req-data timing). signal idxA_valid : std_logic; @@ -465,9 +467,12 @@ begin out_valid => arb_out_valid, out_ready => arb_out_ready, out_data => arbo_sData, - out_index => idxA_index + out_index => arb_out_index ); + idxA_index <= arb_out_index; + idxC_index <= arb_out_index; + bms_wreq_last <= arbo_sData(BQI(2)); bms_wreq_addr <= arbo_sData(BQI(2)-1 downto BQI(1)); bms_wreq_len <= arbo_sData(BQI(1)-1 downto BQI(0)); From 974a441b4ae897c5f429aca29f3f9cacbd4e6a15 Mon Sep 17 00:00:00 2001 From: Jeroen van Straten Date: Wed, 6 Jan 2021 16:35:22 +0100 Subject: [PATCH 4/9] Add write response channel to AXI write converter --- hardware/axi/AxiWriteConverter.vhd | 171 +++++++++++++++++++++++------ hardware/axi/Axi_pkg.vhd | 20 +++- 2 files changed, 152 insertions(+), 39 deletions(-) diff --git a/hardware/axi/AxiWriteConverter.vhd b/hardware/axi/AxiWriteConverter.vhd index b83d82010..892892723 100644 --- a/hardware/axi/AxiWriteConverter.vhd +++ b/hardware/axi/AxiWriteConverter.vhd @@ -53,8 +53,10 @@ entity AxiWriteConverter is SLV_REQ_SLICE_DEPTH : natural := 2; SLV_DAT_SLICE_DEPTH : natural := 2; + SLV_REP_SLICE_DEPTH : natural := 2; MST_REQ_SLICE_DEPTH : natural := 2; - MST_DAT_SLICE_DEPTH : natural := 2 + MST_DAT_SLICE_DEPTH : natural := 2; + MST_REP_SLICE_DEPTH : natural := 2 ); @@ -64,10 +66,11 @@ entity AxiWriteConverter is -- Fletcher bus -- Write address channel - slv_bus_wreq_valid : in std_logic; + slv_bus_wreq_valid : in std_logic; slv_bus_wreq_ready : out std_logic; - slv_bus_wreq_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); - slv_bus_wreq_len : in std_logic_vector(SLAVE_LEN_WIDTH-1 downto 0); + slv_bus_wreq_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); + slv_bus_wreq_len : in std_logic_vector(SLAVE_LEN_WIDTH-1 downto 0); + slv_bus_wreq_last : in std_logic; -- Write data channel slv_bus_wdat_valid : in std_logic; @@ -76,20 +79,34 @@ entity AxiWriteConverter is slv_bus_wdat_strobe : in std_logic_vector(SLAVE_DATA_WIDTH/8-1 downto 0); slv_bus_wdat_last : in std_logic; + -- Write response channel + slv_bus_wrep_valid : out std_logic; + slv_bus_wrep_ready : in std_logic; + slv_bus_wrep_ok : out std_logic; + -- AXI BUS - -- Read address channel + -- Write address channel + -- awuser(0) is used to specify that the write request is the last request + -- for a buffer, to specify that any write buffers must be flushed to main + -- memory. m_axi_awaddr : out std_logic_vector(ADDR_WIDTH-1 downto 0); m_axi_awlen : out std_logic_vector(MASTER_LEN_WIDTH-1 downto 0); m_axi_awvalid : out std_logic; m_axi_awready : in std_logic; m_axi_awsize : out std_logic_vector(2 downto 0); + m_axi_awuser : out std_logic_vector(0 downto 0); - -- Read data channel + -- Write data channel m_axi_wvalid : out std_logic; m_axi_wready : in std_logic; m_axi_wdata : out std_logic_vector(MASTER_DATA_WIDTH-1 downto 0); m_axi_wstrb : out std_logic_vector(MASTER_DATA_WIDTH/8-1 downto 0); - m_axi_wlast : out std_logic + m_axi_wlast : out std_logic; + + -- Write response channel + m_axi_bvalid : in std_logic; + m_axi_bready : out std_logic; + m_axi_bresp : in std_logic_vector(1 downto 0) ); end entity AxiWriteConverter; @@ -115,21 +132,29 @@ architecture rtl of AxiWriteConverter is signal buf_mst_wreq_ready : std_logic; signal buf_mst_wreq_addr : std_logic_vector(ADDR_WIDTH-1 downto 0); signal buf_mst_wreq_len : std_logic_vector(MASTER_LEN_WIDTH downto 0); + signal buf_mst_wreq_last : std_logic; signal buf_mst_wdat_valid : std_logic; signal buf_mst_wdat_ready : std_logic; signal buf_mst_wdat_data : std_logic_vector(MASTER_DATA_WIDTH-1 downto 0); signal buf_mst_wdat_strobe : std_logic_vector(MASTER_DATA_WIDTH/8-1 downto 0); signal buf_mst_wdat_last : std_logic; + signal buf_mst_wrep_valid : std_logic; + signal buf_mst_wrep_ready : std_logic; + signal buf_mst_wrep_ok : std_logic; signal buf_slv_wreq_valid : std_logic; signal buf_slv_wreq_ready : std_logic; signal buf_slv_wreq_addr : std_logic_vector(ADDR_WIDTH-1 downto 0); signal buf_slv_wreq_len : std_logic_vector(MASTER_LEN_WIDTH downto 0); + signal buf_slv_wreq_last : std_logic; signal buf_slv_wdat_valid : std_logic; signal buf_slv_wdat_ready : std_logic; signal buf_slv_wdat_data : std_logic_vector(MASTER_DATA_WIDTH-1 downto 0); signal buf_slv_wdat_strobe : std_logic_vector(MASTER_DATA_WIDTH/8-1 downto 0); signal buf_slv_wdat_last : std_logic; + signal buf_slv_wrep_valid : std_logic; + signal buf_slv_wrep_ready : std_logic; + signal buf_slv_wrep_ok : std_logic; -- StreamGearboxParallelizer input & output for data signal ser_dat_i_ready : std_logic; @@ -159,6 +184,7 @@ architecture rtl of AxiWriteConverter is -- Fletcher Write Address Channel Indices constant FWACI : nat_array := cumulative(( + 2 => 1, 1 => slv_bus_wreq_addr'length, 0 => slv_bus_wreq_len'length )); @@ -172,6 +198,7 @@ architecture rtl of AxiWriteConverter is -- AXI Write Address Channel Indices constant AWACI : nat_array := cumulative(( + 2 => m_axi_awuser'length, 1 => m_axi_awaddr'length, 0 => m_axi_awlen'length )); @@ -183,33 +210,41 @@ architecture rtl of AxiWriteConverter is 0 => 1 )); - signal int_slv_bus_wreq_addr : std_logic_vector(ADDR_WIDTH-1 downto 0); - signal int_slv_bus_wreq_len : std_logic_vector(SLAVE_LEN_WIDTH-1 downto 0); signal int_slv_bus_wreq_valid : std_logic; signal int_slv_bus_wreq_ready : std_logic; + signal int_slv_bus_wreq_addr : std_logic_vector(ADDR_WIDTH-1 downto 0); + signal int_slv_bus_wreq_len : std_logic_vector(SLAVE_LEN_WIDTH-1 downto 0); + signal int_slv_bus_wreq_last : std_logic; + signal int_slv_bus_wdat_valid : std_logic; + signal int_slv_bus_wdat_ready : std_logic; signal int_slv_bus_wdat_data : std_logic_vector(SLAVE_DATA_WIDTH-1 downto 0); signal int_slv_bus_wdat_strobe: std_logic_vector(SLAVE_DATA_WIDTH/8-1 downto 0); signal int_slv_bus_wdat_last : std_logic; - signal int_slv_bus_wdat_valid : std_logic; - signal int_slv_bus_wdat_ready : std_logic; - signal int_m_axi_awaddr : std_logic_vector(ADDR_WIDTH-1 downto 0); - signal int_m_axi_awlen : std_logic_vector(MASTER_LEN_WIDTH-1 downto 0); + signal int_slv_bus_wrep_valid : std_logic; + signal int_slv_bus_wrep_ready : std_logic; + signal int_slv_bus_wrep_ok : std_logic; signal int_m_axi_awvalid : std_logic; signal int_m_axi_awready : std_logic; + signal int_m_axi_awaddr : std_logic_vector(ADDR_WIDTH-1 downto 0); + signal int_m_axi_awlen : std_logic_vector(MASTER_LEN_WIDTH-1 downto 0); signal int_m_axi_awsize : std_logic_vector(2 downto 0); + signal int_m_axi_awuser : std_logic_vector(0 downto 0); + signal int_m_axi_wvalid : std_logic; + signal int_m_axi_wready : std_logic; signal int_m_axi_wdata : std_logic_vector(MASTER_DATA_WIDTH-1 downto 0); signal int_m_axi_wstrb : std_logic_vector(MASTER_DATA_WIDTH/8-1 downto 0); signal int_m_axi_wlast : std_logic; - signal int_m_axi_wvalid : std_logic; - signal int_m_axi_wready : std_logic; + signal int_m_axi_bvalid : std_logic; + signal int_m_axi_bready : std_logic; + signal int_m_axi_bresp : std_logic_vector(1 downto 0); - signal int_slv_bus_wreq_all : std_logic_vector(FWACI(2)-1 downto 0); + signal int_slv_bus_wreq_all : std_logic_vector(FWACI(3)-1 downto 0); signal int_slv_bus_wdat_all : std_logic_vector(FWDCI(3)-1 downto 0); - signal int_m_axi_awall : std_logic_vector(AWACI(2)-1 downto 0); + signal int_m_axi_awall : std_logic_vector(AWACI(3)-1 downto 0); signal int_m_axi_wall : std_logic_vector(AWDCI(3)-1 downto 0); - signal slv_bus_wreq_all : std_logic_vector(FWACI(2)-1 downto 0); + signal slv_bus_wreq_all : std_logic_vector(FWACI(3)-1 downto 0); signal slv_bus_wdat_all : std_logic_vector(FWDCI(3)-1 downto 0); - signal m_axi_awall : std_logic_vector(AWACI(2)-1 downto 0); + signal m_axi_awall : std_logic_vector(AWACI(3)-1 downto 0); signal m_axi_wall : std_logic_vector(AWDCI(3)-1 downto 0); begin @@ -223,16 +258,20 @@ begin -- If the ratio is 1, simply pass through, but convert to AXI len pass_through_gen: if RATIO = 1 generate + int_m_axi_awvalid <= int_slv_bus_wreq_valid; int_slv_bus_wreq_ready <= int_m_axi_awready; int_m_axi_awaddr <= int_slv_bus_wreq_addr; int_m_axi_awlen <= slv(resize(u(int_slv_bus_wreq_len) - 1, MASTER_LEN_WIDTH)); - int_m_axi_awvalid <= int_slv_bus_wreq_valid; + int_m_axi_wvalid <= int_slv_bus_wdat_valid; int_slv_bus_wdat_ready <= int_m_axi_wready; int_m_axi_wdata <= int_slv_bus_wdat_data; int_m_axi_wstrb <= int_slv_bus_wdat_strobe; int_m_axi_wlast <= int_slv_bus_wdat_last; - int_m_axi_wvalid <= int_slv_bus_wdat_valid; + + int_slv_bus_wrep_valid <= int_m_axi_bvalid; + int_m_axi_bready <= int_slv_bus_wrep_ready; + int_slv_bus_wrep_ok <= '0' when int_m_axi_bresp /= "00" else '1'; end generate; -- If the ratio is larger than 1, instantiate the parallelizer, etc.. @@ -241,18 +280,19 @@ begin -- Write Request channels ----------------------------------------------------------------------------- -- From slave port to BusBuffer - int_slv_bus_wreq_ready <= buf_mst_wreq_ready; buf_mst_wreq_valid <= int_slv_bus_wreq_valid; + int_slv_bus_wreq_ready <= buf_mst_wreq_ready; buf_mst_wreq_addr <= int_slv_bus_wreq_addr; -- Length conversion; get the number of full words on the master -- Thus we have to shift with the log2ceil of the ratio, but round up -- in case its not an integer multiple of the ratio. buf_mst_wreq_len <= slv(resize(shift(u(int_slv_bus_wreq_len), -LEN_SHIFT, true), MASTER_LEN_WIDTH+1)); + buf_mst_wreq_last <= int_slv_bus_wreq_last; -- From BusBuffer to AXI master port + int_m_axi_awvalid <= buf_slv_wreq_valid; buf_slv_wreq_ready <= m_axi_awready; int_m_axi_awaddr <= buf_slv_wreq_addr; - int_m_axi_awvalid <= buf_slv_wreq_valid; -- Convert to AXI spec: int_m_axi_awlen <= slv(resize(u(buf_slv_wreq_len) - 1, MASTER_LEN_WIDTH)); ----------------------------------------------------------------------------- @@ -264,6 +304,18 @@ begin ser_stb_i_data <= int_slv_bus_wdat_strobe; ser_stb_i_last <= int_slv_bus_wdat_last; + ----------------------------------------------------------------------------- + -- Write Response channels + ----------------------------------------------------------------------------- + -- From slave port to BusBuffer + int_slv_bus_wrep_valid <= buf_mst_wrep_valid; + buf_mst_wrep_ready <= int_slv_bus_wrep_ready; + int_slv_bus_wrep_ok <= buf_mst_wrep_ok; + + -- From BusBuffer to AXI master port + buf_slv_wrep_valid <= int_m_axi_bvalid; + int_m_axi_bready <= buf_slv_wrep_ready; + buf_slv_wrep_ok <= '0' when int_m_axi_bresp /= "00" else '1'; -- Split the write data stream into data and strobe for parallelization wdat_split: StreamSync @@ -372,20 +424,28 @@ begin mst_wreq_ready => buf_mst_wreq_ready, mst_wreq_addr => buf_mst_wreq_addr, mst_wreq_len => buf_mst_wreq_len, + mst_wreq_last => buf_mst_wreq_last, mst_wdat_valid => buf_mst_wdat_valid, mst_wdat_ready => buf_mst_wdat_ready, mst_wdat_data => buf_mst_wdat_data, mst_wdat_strobe => buf_mst_wdat_strobe, mst_wdat_last => buf_mst_wdat_last, + mst_wrep_valid => buf_mst_wrep_valid, + mst_wrep_ready => buf_mst_wrep_ready, + mst_wrep_ok => buf_mst_wrep_ok, slv_wreq_valid => buf_slv_wreq_valid, slv_wreq_ready => buf_slv_wreq_ready, slv_wreq_addr => buf_slv_wreq_addr, slv_wreq_len => buf_slv_wreq_len, + slv_wreq_last => buf_slv_wreq_last, slv_wdat_valid => buf_slv_wdat_valid, slv_wdat_ready => buf_slv_wdat_ready, slv_wdat_data => buf_slv_wdat_data, slv_wdat_strobe => buf_slv_wdat_strobe, - slv_wdat_last => buf_slv_wdat_last + slv_wdat_last => buf_slv_wdat_last, + slv_wrep_valid => buf_slv_wrep_valid, + slv_wrep_ready => buf_slv_wrep_ready, + slv_wrep_ok => buf_slv_wrep_ok ); end generate; @@ -395,15 +455,20 @@ begin buf_mst_wreq_ready <= buf_slv_wreq_ready; buf_slv_wreq_addr <= buf_mst_wreq_addr; buf_slv_wreq_len <= buf_mst_wreq_len; + buf_slv_wreq_last <= buf_mst_wreq_last; buf_slv_wdat_valid <= buf_mst_wdat_valid; buf_mst_wdat_ready <= buf_slv_wdat_ready; buf_slv_wdat_data <= buf_mst_wdat_data; buf_slv_wdat_strobe <= buf_mst_wdat_strobe; buf_slv_wdat_last <= buf_mst_wdat_last; + + buf_mst_wrep_valid <= buf_slv_wrep_valid; + buf_slv_wrep_ready <= buf_mst_wrep_ready; + buf_mst_wrep_ok <= buf_slv_wrep_ok; end generate; - -- Write data channel BusWriteBuffer to AXI Master Port + -- Write data channel BusWriteBuffer to AXI Master Port int_m_axi_wvalid <= buf_slv_wdat_valid; buf_slv_wdat_ready <= int_m_axi_wready; int_m_axi_wdata <= buf_slv_wdat_data; @@ -412,14 +477,15 @@ begin end generate; - -- Fletcher write request slice ---------------------------------------------- - slv_bus_wreq_all <= slv_bus_wreq_addr + -- Fletcher write request slice ---------------------------------------------- + slv_bus_wreq_all <= slv_bus_wreq_last + & slv_bus_wreq_addr & slv_bus_wreq_len; fwac_slice : StreamBuffer generic map ( MIN_DEPTH => SLV_REQ_SLICE_DEPTH, - DATA_WIDTH => FWACI(2) + DATA_WIDTH => FWACI(3) ) port map ( clk => clk, @@ -432,6 +498,7 @@ begin out_data => int_slv_bus_wreq_all ); + int_slv_bus_wreq_last <= int_slv_bus_wreq_all(FWACI(2)); int_slv_bus_wreq_addr <= int_slv_bus_wreq_all(FWACI(2)-1 downto FWACI(1)); int_slv_bus_wreq_len <= int_slv_bus_wreq_all(FWACI(1)-1 downto FWACI(0)); @@ -440,7 +507,7 @@ begin & slv_bus_wdat_strobe & slv_bus_wdat_last; - frdc_slice : StreamBuffer + fwdc_slice : StreamBuffer generic map ( MIN_DEPTH => SLV_DAT_SLICE_DEPTH, DATA_WIDTH => FWDCI(3) @@ -460,14 +527,32 @@ begin int_slv_bus_wdat_strobe <= int_slv_bus_wdat_all(FWDCI(2)-1 downto FWDCI(1)); int_slv_bus_wdat_last <= int_slv_bus_wdat_all( FWDCI(0)); + -- Fletcher write response slice --------------------------------------------- + fwrc_slice : StreamBuffer + generic map ( + MIN_DEPTH => SLV_REP_SLICE_DEPTH, + DATA_WIDTH => 1 + ) + port map ( + clk => clk, + reset => reset, + in_ready => int_slv_bus_wrep_ready, + in_valid => int_slv_bus_wrep_valid, + in_data(0) => int_slv_bus_wrep_ok, + out_ready => slv_bus_wrep_ready, + out_valid => slv_bus_wrep_valid, + out_data(0) => slv_bus_wrep_ok + ); + -- AXI write address slice --------------------------------------------------- - int_m_axi_awall <= int_m_axi_awaddr + int_m_axi_awall <= int_m_axi_awuser + & int_m_axi_awaddr & int_m_axi_awlen; - arac_slice : StreamBuffer + awac_slice : StreamBuffer generic map ( MIN_DEPTH => MST_REQ_SLICE_DEPTH, - DATA_WIDTH => AWACI(2) + DATA_WIDTH => AWACI(3) ) port map ( clk => clk, @@ -480,6 +565,7 @@ begin out_data => m_axi_awall ); + m_axi_awuser <= m_axi_awall(AWACI(3)-1 downto AWACI(2)); m_axi_awaddr <= m_axi_awall(AWACI(2)-1 downto AWACI(1)); m_axi_awlen <= m_axi_awall(AWACI(1)-1 downto AWACI(0)); @@ -488,7 +574,7 @@ begin & int_m_axi_wstrb & int_m_axi_wlast; - ardc_slice : StreamBuffer + awdc_slice : StreamBuffer generic map ( MIN_DEPTH => MST_DAT_SLICE_DEPTH, DATA_WIDTH => AWDCI(3) @@ -508,6 +594,23 @@ begin m_axi_wstrb <= m_axi_wall(AWDCI(2)-1 downto AWDCI(1)); m_axi_wlast <= m_axi_wall( AWDCI(0)); - + -- AXI write response slice -------------------------------------------------- + awrc_slice : StreamBuffer + generic map ( + MIN_DEPTH => MST_REP_SLICE_DEPTH, + DATA_WIDTH => 2 + ) + port map ( + clk => clk, + reset => reset, + in_ready => m_axi_bready, + in_valid => m_axi_bvalid, + in_data => m_axi_bresp, + out_ready => int_m_axi_bready, + out_valid => int_m_axi_bvalid, + out_data => int_m_axi_bresp + ); + + end architecture rtl; diff --git a/hardware/axi/Axi_pkg.vhd b/hardware/axi/Axi_pkg.vhd index b159026b5..eedba085e 100644 --- a/hardware/axi/Axi_pkg.vhd +++ b/hardware/axi/Axi_pkg.vhd @@ -123,38 +123,48 @@ package Axi_pkg is ENABLE_FIFO : boolean := true; SLV_REQ_SLICE_DEPTH : natural := 2; SLV_DAT_SLICE_DEPTH : natural := 2; + SLV_REP_SLICE_DEPTH : natural := 2; MST_REQ_SLICE_DEPTH : natural := 2; - MST_DAT_SLICE_DEPTH : natural := 2 - ); - port ( + MST_DAT_SLICE_DEPTH : natural := 2; + MST_REP_SLICE_DEPTH : natural := 2 + ); + port ( clk : in std_logic; reset_n : in std_logic; slv_bus_wreq_valid : in std_logic; slv_bus_wreq_ready : out std_logic; slv_bus_wreq_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); slv_bus_wreq_len : in std_logic_vector(SLAVE_LEN_WIDTH-1 downto 0); + slv_bus_wreq_last : in std_logic; slv_bus_wdat_valid : in std_logic; slv_bus_wdat_ready : out std_logic; slv_bus_wdat_data : in std_logic_vector(SLAVE_DATA_WIDTH-1 downto 0); slv_bus_wdat_strobe : in std_logic_vector(SLAVE_DATA_WIDTH/8-1 downto 0); slv_bus_wdat_last : in std_logic; + slv_bus_wrep_valid : out std_logic; + slv_bus_wrep_ready : in std_logic; + slv_bus_wrep_ok : out std_logic; m_axi_awaddr : out std_logic_vector(ADDR_WIDTH-1 downto 0); m_axi_awlen : out std_logic_vector(MASTER_LEN_WIDTH-1 downto 0); m_axi_awvalid : out std_logic; m_axi_awready : in std_logic; m_axi_awsize : out std_logic_vector(2 downto 0); + m_axi_awuser : out std_logic_vector(0 downto 0); m_axi_wvalid : out std_logic; m_axi_wready : in std_logic; m_axi_wdata : out std_logic_vector(MASTER_DATA_WIDTH-1 downto 0); m_axi_wstrb : out std_logic_vector(MASTER_DATA_WIDTH/8-1 downto 0); - m_axi_wlast : out std_logic + m_axi_wlast : out std_logic; + m_axi_bvalid : in std_logic; + m_axi_bready : out std_logic; + m_axi_bresp : in std_logic_vector(1 downto 0) ); end component; component AxiMmio is generic ( BUS_ADDR_WIDTH : natural := 32; - BUS_DATA_WIDTH : natural := 32; + BUS_DATA_WIDTH : natural := 32; NUM_REGS : natural; REG_CONFIG : string := ""; REG_RESET : string := ""; From 03ee788b87ff5ba3e0ec0eca2f8db46bf3c4a719 Mon Sep 17 00:00:00 2001 From: Jeroen van Straten Date: Wed, 6 Jan 2021 16:37:03 +0100 Subject: [PATCH 5/9] Remove axi_top component from axi_pkg It's not up-to-date now, and probably isn't used? --- hardware/axi/Axi_pkg.vhd | 55 ---------------------------------------- 1 file changed, 55 deletions(-) diff --git a/hardware/axi/Axi_pkg.vhd b/hardware/axi/Axi_pkg.vhd index eedba085e..c4e8a8c0d 100644 --- a/hardware/axi/Axi_pkg.vhd +++ b/hardware/axi/Axi_pkg.vhd @@ -19,61 +19,6 @@ use ieee.std_logic_misc.all; package Axi_pkg is - component AxiTop is - generic ( - BUS_ADDR_WIDTH : natural; - BUS_DATA_WIDTH : natural; - BUS_LEN_WIDTH : natural; - BUS_BURST_MAX_LEN : natural; - BUS_BURST_STEP_LEN : natural; - MMIO_ADDR_WIDTH : natural; - MMIO_DATA_WIDTH : natural - ); - port ( - kcd_clk : in std_logic; - kcd_reset : in std_logic; - bcd_clk : in std_logic; - bcd_reset : in std_logic; - m_axi_araddr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - m_axi_arlen : out std_logic_vector(7 downto 0); - m_axi_arvalid : out std_logic; - m_axi_arready : in std_logic; - m_axi_arsize : out std_logic_vector(2 downto 0); - m_axi_rdata : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - m_axi_rresp : in std_logic_vector(1 downto 0); - m_axi_rlast : in std_logic; - m_axi_rvalid : in std_logic; - m_axi_rready : out std_logic; - m_axi_awvalid : out std_logic; - m_axi_awready : in std_logic; - m_axi_awaddr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - m_axi_awlen : out std_logic_vector(7 downto 0); - m_axi_awsize : out std_logic_vector(2 downto 0); - m_axi_wvalid : out std_logic; - m_axi_wready : in std_logic; - m_axi_wdata : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - m_axi_wlast : out std_logic; - m_axi_wstrb : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - s_axi_awvalid : in std_logic; - s_axi_awready : out std_logic; - s_axi_awaddr : in std_logic_vector(MMIO_ADDR_WIDTH-1 downto 0); - s_axi_wvalid : in std_logic; - s_axi_wready : out std_logic; - s_axi_wdata : in std_logic_vector(MMIO_DATA_WIDTH-1 downto 0); - s_axi_wstrb : in std_logic_vector((MMIO_DATA_WIDTH/8)-1 downto 0); - s_axi_bvalid : out std_logic; - s_axi_bready : in std_logic; - s_axi_bresp : out std_logic_vector(1 downto 0); - s_axi_arvalid : in std_logic; - s_axi_arready : out std_logic; - s_axi_araddr : in std_logic_vector(MMIO_ADDR_WIDTH-1 downto 0); - s_axi_rvalid : out std_logic; - s_axi_rready : in std_logic; - s_axi_rdata : out std_logic_vector(MMIO_DATA_WIDTH-1 downto 0); - s_axi_rresp : out std_logic_vector(1 downto 0) - ); - end component; - component AxiReadConverter is generic ( ADDR_WIDTH : natural; From 4f1a34cd205fa324f9c2da47f955447ca4d171a0 Mon Sep 17 00:00:00 2001 From: Johan Peltenburg Date: Thu, 7 Jan 2021 14:28:19 +0100 Subject: [PATCH 6/9] Reflect addition of write response channel in Fletchgen --- codegen/cpp/fletchgen/src/fletchgen/bus.cc | 11 ++++++--- .../cpp/fletchgen/src/fletchgen/top/axi.cc | 24 ++++++++++++++++--- .../src/fletchgen/top/axi_template.h | 10 ++++++++ .../cpp/fletchgen/src/fletchgen/top/sim.cc | 18 +++++++++++--- .../src/fletchgen/top/sim_template.h | 4 ++++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/codegen/cpp/fletchgen/src/fletchgen/bus.cc b/codegen/cpp/fletchgen/src/fletchgen/bus.cc index 11692a981..ad8b5f632 100644 --- a/codegen/cpp/fletchgen/src/fletchgen/bus.cc +++ b/codegen/cpp/fletchgen/src/fletchgen/bus.cc @@ -37,6 +37,7 @@ using cerata::parameter; using cerata::stream; using cerata::field; using cerata::vector; +using cerata::bit; PARAM_FACTORY(bus_addr_width) PARAM_FACTORY(bus_data_width) @@ -61,17 +62,21 @@ std::shared_ptr bus_write(const std::shared_ptr &addr_width, const std::shared_ptr &data_width, const std::shared_ptr &len_width) { auto wreq = stream(record("", {field("addr", vector(addr_width)), - field("len", vector(len_width))})); + field("len", vector(len_width)), + field("last", last())})); auto wdat = stream(record("", {field("data", vector(data_width)), field("strobe", vector(data_width / 8)), field("last", last())})); + auto wrep = stream(record("", {field("ok", bit())})); auto result = record("", {field("wreq", wreq), - field("wdat", wdat)}); + field("wdat", wdat), + field("wrep", wrep)->Reverse()}); return result; } static std::string GetBusArbiterName(BusFunction function) { - return std::string("Bus") + (function == BusFunction::READ ? "Read" : "Write") + "ArbiterVec"; + return std::string("Bus") + (function == BusFunction::READ ? "Read" : "Write") + + "ArbiterVec"; } Component *bus_arbiter(BusFunction function) { diff --git a/codegen/cpp/fletchgen/src/fletchgen/top/axi.cc b/codegen/cpp/fletchgen/src/fletchgen/top/axi.cc index 4b7420f9d..26a6f0cc8 100644 --- a/codegen/cpp/fletchgen/src/fletchgen/top/axi.cc +++ b/codegen/cpp/fletchgen/src/fletchgen/top/axi.cc @@ -125,22 +125,32 @@ std::string GenerateAXITop(const Mantle &mantle, " wr_mst_wreq_ready : in std_logic;\n" " wr_mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n" " wr_mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n" + " wr_mst_wreq_last : out std_logic;\n" " wr_mst_wdat_valid : out std_logic;\n" " wr_mst_wdat_ready : in std_logic;\n" " wr_mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n" " wr_mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n" - " wr_mst_wdat_last : out std_logic;"); + " wr_mst_wdat_last : out std_logic;" + " wr_mst_wrep_valid : in std_logic;" + " wr_mst_wrep_ready : out std_logic;" + " wr_mst_wrep_ok : in std_logic;" + ); t.Replace("MST_WREQ_INSTANTIATE", " wr_mst_wreq_valid => wr_mst_wreq_valid,\n" " wr_mst_wreq_ready => wr_mst_wreq_ready,\n" " wr_mst_wreq_addr => wr_mst_wreq_addr,\n" " wr_mst_wreq_len => wr_mst_wreq_len,\n" + " wr_mst_wreq_last => wr_mst_wreq_last,\n" " wr_mst_wdat_valid => wr_mst_wdat_valid,\n" " wr_mst_wdat_ready => wr_mst_wdat_ready,\n" " wr_mst_wdat_data => wr_mst_wdat_data,\n" " wr_mst_wdat_strobe => wr_mst_wdat_strobe,\n" - " wr_mst_wdat_last => wr_mst_wdat_last,"); + " wr_mst_wdat_last => wr_mst_wdat_last,\n" + " wr_mst_wrep_valid => wr_mst_wrep_valid,\n" + " wr_mst_wrep_ready => wr_mst_wrep_ready,\n" + " wr_mst_wrep_ok => wr_mst_wrep_ok,"); + t.Replace("AXI_WRITE_CONVERTER", " -----------------------------------------------------------------------------\n" " -- AXI write converter\n" @@ -168,21 +178,29 @@ std::string GenerateAXITop(const Mantle &mantle, " slv_bus_wreq_len => wr_mst_wreq_len,\n" " slv_bus_wreq_valid => wr_mst_wreq_valid,\n" " slv_bus_wreq_ready => wr_mst_wreq_ready,\n" + " slv_bus_wreq_last => wr_mst_wreq_last,\n" " slv_bus_wdat_data => wr_mst_wdat_data,\n" " slv_bus_wdat_strobe => wr_mst_wdat_strobe,\n" " slv_bus_wdat_last => wr_mst_wdat_last,\n" " slv_bus_wdat_valid => wr_mst_wdat_valid,\n" " slv_bus_wdat_ready => wr_mst_wdat_ready,\n" + " slv_bus_wrep_valid => wr_mst_wrep_valid,\n" + " slv_bus_wrep_ready => wr_mst_wrep_ready,\n" + " slv_bus_wrep_ok => wr_mst_wrep_ok,\n" " m_axi_awaddr => m_axi_awaddr,\n" " m_axi_awlen => m_axi_awlen,\n" " m_axi_awvalid => m_axi_awvalid,\n" " m_axi_awready => m_axi_awready,\n" " m_axi_awsize => m_axi_awsize,\n" + " m_axi_awuser => m_axi_awuser,\n" " m_axi_wdata => m_axi_wdata,\n" " m_axi_wstrb => m_axi_wstrb,\n" " m_axi_wlast => m_axi_wlast,\n" " m_axi_wvalid => m_axi_wvalid,\n" - " m_axi_wready => m_axi_wready\n" + " m_axi_wready => m_axi_wready,\n" + " m_axi_bvalid => m_axi_bvalid,\n" + " m_axi_bready => m_axi_bready,\n" + " m_axi_bresp => m_axi_bresp\n" " );"); } else { t.Replace("MST_WREQ_DECLARE", ""); diff --git a/codegen/cpp/fletchgen/src/fletchgen/top/axi_template.h b/codegen/cpp/fletchgen/src/fletchgen/top/axi_template.h index a2e65eafe..f0db9eb72 100644 --- a/codegen/cpp/fletchgen/src/fletchgen/top/axi_template.h +++ b/codegen/cpp/fletchgen/src/fletchgen/top/axi_template.h @@ -100,6 +100,7 @@ static char axi_source[] = " m_axi_awaddr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n" " m_axi_awlen : out std_logic_vector(7 downto 0);\n" " m_axi_awsize : out std_logic_vector(2 downto 0);\n" + " m_axi_awuser : out std_logic_vector(0 downto 0);\n" "\n" " -- Write data channel\n" " m_axi_wvalid : out std_logic := '0';\n" @@ -108,6 +109,10 @@ static char axi_source[] = " m_axi_wlast : out std_logic;\n" " m_axi_wstrb : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n" "\n" + " -- Write response channel\n" + " m_axi_bvalid : in std_logic;\n" + " m_axi_bready : out std_logic;\n" + " m_axi_bresp : in std_logic_vector(1 downto 0);\n" " ---------------------------------------------------------------------------\n" " -- AXI4-lite Slave as MMIO interface\n" " ---------------------------------------------------------------------------\n" @@ -165,11 +170,16 @@ static char axi_source[] = " signal wr_mst_wreq_ready : std_logic;\n" " signal wr_mst_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n" " signal wr_mst_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n" + " signal wr_mst_wreq_last : std_logic;\n" " signal wr_mst_wdat_valid : std_logic;\n" " signal wr_mst_wdat_ready : std_logic;\n" " signal wr_mst_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n" " signal wr_mst_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n" " signal wr_mst_wdat_last : std_logic;\n" + " signal wr_mst_wrep_valid : std_logic;\n" + " signal wr_mst_wrep_ready : std_logic;\n" + " signal wr_mst_wrep_ok : std_logic;\n" + "\n" "begin\n" "\n" " -- Active low reset\n" diff --git a/codegen/cpp/fletchgen/src/fletchgen/top/sim.cc b/codegen/cpp/fletchgen/src/fletchgen/top/sim.cc index a7e70cb9c..03cec1ff8 100644 --- a/codegen/cpp/fletchgen/src/fletchgen/top/sim.cc +++ b/codegen/cpp/fletchgen/src/fletchgen/top/sim.cc @@ -266,11 +266,15 @@ std::string GenerateSimTop(const Design &design, " wreq_ready => bus_wreq_ready,\n" " wreq_addr => bus_wreq_addr,\n" " wreq_len => bus_wreq_len,\n" + " wreq_last => bus_wreq_last,\n" " wdat_valid => bus_wdat_valid,\n" " wdat_ready => bus_wdat_ready,\n" " wdat_data => bus_wdat_data,\n" " wdat_strobe => bus_wdat_strobe,\n" - " wdat_last => bus_wdat_last\n" + " wdat_last => bus_wdat_last,\n" + " wrep_valid => bus_wrep_valid,\n" + " wrep_ready => bus_wrep_ready,\n" + " wrep_ok => bus_wrep_ok\n" " );"); t.Replace("MST_WREQ_DECLARE", @@ -278,22 +282,30 @@ std::string GenerateSimTop(const Design &design, " wr_mst_wreq_ready : in std_logic;\n" " wr_mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n" " wr_mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n" + " wr_mst_wreq_last : out std_logic;\n" " wr_mst_wdat_valid : out std_logic;\n" " wr_mst_wdat_ready : in std_logic;\n" " wr_mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n" " wr_mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n" - " wr_mst_wdat_last : out std_logic;"); + " wr_mst_wdat_last : out std_logic;" + " wr_mst_wrep_valid : in std_logic;\n" + " wr_mst_wrep_ready : out std_logic;\n" + " wr_mst_wrep_ok : in std_logic;\n"); t.Replace("MST_WREQ_INSTANTIATE", " wr_mst_wreq_valid => bus_wreq_valid,\n" " wr_mst_wreq_ready => bus_wreq_ready,\n" " wr_mst_wreq_addr => bus_wreq_addr,\n" " wr_mst_wreq_len => bus_wreq_len,\n" + " wr_mst_wreq_last => bus_wreq_last,\n" " wr_mst_wdat_valid => bus_wdat_valid,\n" " wr_mst_wdat_ready => bus_wdat_ready,\n" " wr_mst_wdat_data => bus_wdat_data,\n" " wr_mst_wdat_strobe => bus_wdat_strobe,\n" - " wr_mst_wdat_last => bus_wdat_last,"); + " wr_mst_wdat_last => bus_wdat_last,\n" + " wr_mst_wrep_valid => bus_wrep_valid,\n" + " wr_mst_wrep_ready => bus_wrep_ready,\n" + " wr_mst_wrep_ok => bus_wrep_ok,"); } else { t.Replace("BUS_WRITE_SLAVE_MOCK", ""); t.Replace("MST_WREQ_DECLARE", ""); diff --git a/codegen/cpp/fletchgen/src/fletchgen/top/sim_template.h b/codegen/cpp/fletchgen/src/fletchgen/top/sim_template.h index 5b6c1d44e..d44fe9c6f 100644 --- a/codegen/cpp/fletchgen/src/fletchgen/top/sim_template.h +++ b/codegen/cpp/fletchgen/src/fletchgen/top/sim_template.h @@ -157,6 +157,7 @@ static char sim_source[] = " signal bus_rdat_valid : std_logic;\n" " signal bus_rdat_ready : std_logic;\n" " signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n" + " signal bus_wreq_last : std_logic;\n" " signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n" " signal bus_wreq_valid : std_logic;\n" " signal bus_wreq_ready : std_logic;\n" @@ -165,6 +166,9 @@ static char sim_source[] = " signal bus_wdat_last : std_logic;\n" " signal bus_wdat_valid : std_logic;\n" " signal bus_wdat_ready : std_logic;\n" + " signal bus_wrep_ok : std_logic;\n" + " signal bus_wrep_valid : std_logic;\n" + " signal bus_wrep_ready : std_logic;\n" "\n" " procedure mmio_write32 (constant idx : in natural;\n" " constant data : in std_logic_vector(31 downto 0);\n" From 1dcc7bc93e6396ff040512de05541c00d3667b00 Mon Sep 17 00:00:00 2001 From: Johan Peltenburg Date: Thu, 7 Jan 2021 14:28:30 +0100 Subject: [PATCH 7/9] Reflect addition of write response channel in tests and examples --- codegen/test/primmap/Makefile | 3 +- codegen/test/primmap/generate-input.py | 21 ++++ codegen/test/primmap/in.rb | Bin 0 -> 850 bytes codegen/test/primmap/out.as | Bin 0 -> 288 bytes codegen/test/primmap/twoprimread.rb | Bin 1090 -> 0 bytes codegen/test/primmap/twoprimwrite.as | Bin 408 -> 0 bytes examples/stringwrite/hardware/Makefile | 2 +- .../{generate-schema.py => generate-input.py} | 0 .../stringwrite/hardware/vhdl/SimTop_tc.vhd | 111 +++++++++++------- 9 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 codegen/test/primmap/generate-input.py create mode 100644 codegen/test/primmap/in.rb create mode 100644 codegen/test/primmap/out.as delete mode 100644 codegen/test/primmap/twoprimread.rb delete mode 100644 codegen/test/primmap/twoprimwrite.as rename examples/stringwrite/hardware/{generate-schema.py => generate-input.py} (100%) diff --git a/codegen/test/primmap/Makefile b/codegen/test/primmap/Makefile index 61a230789..b7995ba2f 100644 --- a/codegen/test/primmap/Makefile +++ b/codegen/test/primmap/Makefile @@ -1,7 +1,8 @@ .PHONY: clean sim all: - fletchgen -r twoprimread.rb -i twoprimwrite.as -s memory.srec -l dot vhdl --sim --regs c:8:add:0x01 s:32:sum + python3 generate-input.py + fletchgen -r in.rb -i out.as -s memory.srec -l vhdl dot --sim --regs c:8:add:0x01 s:32:sum sim: rm -f vhdl/Kernel.gen.vhd diff --git a/codegen/test/primmap/generate-input.py b/codegen/test/primmap/generate-input.py new file mode 100644 index 000000000..4d9ed2b1f --- /dev/null +++ b/codegen/test/primmap/generate-input.py @@ -0,0 +1,21 @@ +import pyarrow as pa + +# Create a field that can be interpreted as a "listprim" ArrayReader/Writer +input_schema = pa.schema([pa.field('A', pa.int8(), nullable=False), + pa.field('B', pa.int8(), nullable=False)]) +input_schema = input_schema.with_metadata({b'fletcher_mode': b'read', b'fletcher_name': b'R'}) + +output_schema = pa.schema([pa.field('C', pa.int8(), nullable=False), + pa.field('D', pa.int8(), nullable=False)]) +output_schema = output_schema.with_metadata({b'fletcher_mode': b'write', b'fletcher_name': b'W'}) + +batch_data = [pa.array([1, -3, 3, -7], pa.int8()), + pa.array([4, 2, -6, -9], pa.int8())] + +input_batch = pa.RecordBatch.from_arrays(batch_data, schema=input_schema) +writer_in = pa.RecordBatchFileWriter('in.rb', input_schema) +writer_in.write(input_batch) +writer_in.close() + +serialized_out_schema = output_schema.serialize() +pa.output_stream('out.as').write(serialized_out_schema) diff --git a/codegen/test/primmap/in.rb b/codegen/test/primmap/in.rb new file mode 100644 index 0000000000000000000000000000000000000000..0af9eb9c225cd8d5c13b8a12bcf56ec8d1a78136 GIT binary patch literal 850 zcmd^8u};H441GyM8%0-?p+X%P8M=03Y!Cw*QWh2@RM8*?3RT6&b?nejVBk+skx+Th zcNYc3AMhlf{cOiRTbHV?uWzQnffy%138BC-`Zz*Pi%7E8??|)YUzrW0)aSu|XPun( zm@=e1JTy(GT6AfbL z{fTO-*9E1-$a)McvkbE!J!5P{Q4c|P$}zB9(zZrL!m@`AwekgrldvIYRng0AX1_mW z6y$zJ?eLbOSnNgfhb`Vk%+nlQL>}XcY5!d=-*29L_4ejZKR={3kF@UOI91=KFa0e1 hdPe_*qB`2+Lf6Uz`hs}%w?SMvJ0d4O%+YAYW88^^^&aO&p30Kmp^h14RJ!yRWNW_Fg#1+6$)b!} Jwv)$}%?}XkAUFU3 literal 0 HcmV?d00001 diff --git a/codegen/test/primmap/twoprimread.rb b/codegen/test/primmap/twoprimread.rb deleted file mode 100644 index 1a74a7846a177d064616b68e8e3a4c3da4208e3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1090 zcmeHHy-EW?5T3h@cgwL#kRTR5fUS@R@T}~FYqStTFc(fpj2y8~X=!ccV_4?J=n*9EgPmN=)x}FbBcks4kL1j)QJd z$3i~^AA;wLdi~JU?PR%{)gh*>r!%NB{welpx@0WiNCjs74R`>4M-D`KhvOQ238tU1 zl&_)Y8Fap-@BiGc=8p@O)wp&0qB`x3ubB`x>s-k(@YBkL?;Xkr9;LK_h`nQ9##lsh zF3ckTrayBndNB{w<0xSOTK5S#;tj~jN!W~2Y+{Vg+V71K1#FLnySoSTj#wk@>d_Zv zz!0%ScW=jgUT`n_wf61KeC3SIFxec@d=G76a(GpS$_^H1C}MP<=g?S(yZGP%+Un`^ ag1RFL&Hw){{cj@9?k~T~E%s9Cf5$hQC4TMz diff --git a/codegen/test/primmap/twoprimwrite.as b/codegen/test/primmap/twoprimwrite.as deleted file mode 100644 index 7a473f8a99702f3167a8337db0914d8e5b8e6e87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmb7AF%H5o40K8h5du^p1_qwd2Oz<~4`4$GTD4M3QB=g*k&&6thP%*aW5CkIXU9G} zvDVs`5{ZR2mYEDC5)B4Z1D~HD47+^pxJUq>bX-G6gD-(8kdPw0^0v@Jl z$dg~S*HguNtRs7X`YjLwZ}h+g2OK+K4KUAI`e&!P0_R)&{F|w>qNJ>=Ys}qo#_d;A uac}BuWsdzBjfC%wWr2*dAcyN`_j6gJQOSQ{7xB-0_G-*xAI$HuLGS@e8aXEb diff --git a/examples/stringwrite/hardware/Makefile b/examples/stringwrite/hardware/Makefile index 0277d5735..ea2a780d3 100644 --- a/examples/stringwrite/hardware/Makefile +++ b/examples/stringwrite/hardware/Makefile @@ -1,7 +1,7 @@ .PHONY: sim clean all: - python generate-schema.py + python3 generate-input.py fletchgen -i stringwrite.as -t memory.srec -l vhdl dot --sim --regs c:32:strlen_min c:32:strlen_mask sim: diff --git a/examples/stringwrite/hardware/generate-schema.py b/examples/stringwrite/hardware/generate-input.py similarity index 100% rename from examples/stringwrite/hardware/generate-schema.py rename to examples/stringwrite/hardware/generate-input.py diff --git a/examples/stringwrite/hardware/vhdl/SimTop_tc.vhd b/examples/stringwrite/hardware/vhdl/SimTop_tc.vhd index 930475a0c..444177ecd 100644 --- a/examples/stringwrite/hardware/vhdl/SimTop_tc.vhd +++ b/examples/stringwrite/hardware/vhdl/SimTop_tc.vhd @@ -47,42 +47,51 @@ architecture Behavioral of SimTop_tc is ----------------------------------------------------------------------------- -- Default wrapper component. ----------------------------------------------------------------------------- - component Kernel_Mantle is - generic( - BUS_ADDR_WIDTH : natural + component Kernel_Mantle is + generic ( + INDEX_WIDTH : integer := 32; + TAG_WIDTH : integer := 1; + BUS_ADDR_WIDTH : integer := 64; + BUS_DATA_WIDTH : integer := 512; + BUS_LEN_WIDTH : integer := 8; + BUS_BURST_STEP_LEN : integer := 1; + BUS_BURST_MAX_LEN : integer := 16 ); - port( - bcd_clk : in std_logic; - bcd_reset : in std_logic; - kcd_clk : in std_logic; - kcd_reset : in std_logic; - - wr_mst_wreq_valid : out std_logic; - wr_mst_wreq_ready : in std_logic; - wr_mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); - wr_mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); - wr_mst_wdat_valid : out std_logic; - wr_mst_wdat_ready : in std_logic; - wr_mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); - wr_mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); - wr_mst_wdat_last : out std_logic; - mmio_awvalid : in std_logic; - mmio_awready : out std_logic; - mmio_awaddr : in std_logic_vector(31 downto 0); - mmio_wvalid : in std_logic; - mmio_wready : out std_logic; - mmio_wdata : in std_logic_vector(31 downto 0); - mmio_wstrb : in std_logic_vector(3 downto 0); - mmio_bvalid : out std_logic; - mmio_bready : in std_logic; - mmio_bresp : out std_logic_vector(1 downto 0); - mmio_arvalid : in std_logic; - mmio_arready : out std_logic; - mmio_araddr : in std_logic_vector(31 downto 0); - mmio_rvalid : out std_logic; - mmio_rready : in std_logic; - mmio_rdata : out std_logic_vector(31 downto 0); - mmio_rresp : out std_logic_vector(1 downto 0) + port ( + bcd_clk : in std_logic; + bcd_reset : in std_logic; + kcd_clk : in std_logic; + kcd_reset : in std_logic; + mmio_awvalid : in std_logic; + mmio_awready : out std_logic; + mmio_awaddr : in std_logic_vector(31 downto 0); + mmio_wvalid : in std_logic; + mmio_wready : out std_logic; + mmio_wdata : in std_logic_vector(31 downto 0); + mmio_wstrb : in std_logic_vector(3 downto 0); + mmio_bvalid : out std_logic; + mmio_bready : in std_logic; + mmio_bresp : out std_logic_vector(1 downto 0); + mmio_arvalid : in std_logic; + mmio_arready : out std_logic; + mmio_araddr : in std_logic_vector(31 downto 0); + mmio_rvalid : out std_logic; + mmio_rready : in std_logic; + mmio_rdata : out std_logic_vector(31 downto 0); + mmio_rresp : out std_logic_vector(1 downto 0); + wr_mst_wreq_valid : out std_logic; + wr_mst_wreq_ready : in std_logic; + wr_mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); + wr_mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0); + wr_mst_wreq_last : out std_logic; + wr_mst_wdat_valid : out std_logic; + wr_mst_wdat_ready : in std_logic; + wr_mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0); + wr_mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0); + wr_mst_wdat_last : out std_logic; + wr_mst_wrep_valid : in std_logic; + wr_mst_wrep_ready : out std_logic; + wr_mst_wrep_ok : in std_logic ); end component; ----------------------------------------------------------------------------- @@ -175,6 +184,7 @@ architecture Behavioral of SimTop_tc is signal bus_rdat_valid : std_logic; signal bus_rdat_ready : std_logic; signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); + signal bus_wreq_last : std_logic; signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0); signal bus_wreq_valid : std_logic; signal bus_wreq_ready : std_logic; @@ -183,6 +193,9 @@ architecture Behavioral of SimTop_tc is signal bus_wdat_last : std_logic; signal bus_wdat_valid : std_logic; signal bus_wdat_ready : std_logic; + signal bus_wrep_ok : std_logic; + signal bus_wrep_valid : std_logic; + signal bus_wrep_ready : std_logic; procedure mmio_write (constant idx : in natural; constant data : in std_logic_vector(31 downto 0); @@ -392,11 +405,15 @@ begin wreq_ready => bus_wreq_ready, wreq_addr => bus_wreq_addr, wreq_len => bus_wreq_len, + wreq_last => bus_wreq_last, wdat_valid => bus_wdat_valid, wdat_ready => bus_wdat_ready, wdat_data => bus_wdat_data, wdat_strobe => bus_wdat_strobe, - wdat_last => bus_wdat_last + wdat_last => bus_wdat_last, + wrep_valid => bus_wrep_valid, + wrep_ready => bus_wrep_ready, + wrep_ok => bus_wrep_ok ); @@ -413,15 +430,19 @@ begin bcd_clk => bcd_clk, bcd_reset => bcd_reset, - wr_mst_wreq_valid => bus_wreq_valid, - wr_mst_wreq_ready => bus_wreq_ready, - wr_mst_wreq_addr => bus_wreq_addr, - wr_mst_wreq_len => bus_wreq_len, - wr_mst_wdat_valid => bus_wdat_valid, - wr_mst_wdat_ready => bus_wdat_ready, - wr_mst_wdat_data => bus_wdat_data, - wr_mst_wdat_strobe => bus_wdat_strobe, - wr_mst_wdat_last => bus_wdat_last, + wr_mst_wreq_valid => bus_wreq_valid, + wr_mst_wreq_ready => bus_wreq_ready, + wr_mst_wreq_addr => bus_wreq_addr, + wr_mst_wreq_len => bus_wreq_len, + wr_mst_wreq_last => bus_wreq_last, + wr_mst_wdat_valid => bus_wdat_valid, + wr_mst_wdat_ready => bus_wdat_ready, + wr_mst_wdat_data => bus_wdat_data, + wr_mst_wdat_strobe => bus_wdat_strobe, + wr_mst_wdat_last => bus_wdat_last, + wr_mst_wrep_valid => bus_wrep_valid, + wr_mst_wrep_ready => bus_wrep_ready, + wr_mst_wrep_ok => bus_wrep_ok, mmio_awvalid => mmio_awvalid, mmio_awready => mmio_awready, mmio_awaddr => mmio_awaddr, From 26dc7a5b01d0d25a9452d597b113e197d40cf37e Mon Sep 17 00:00:00 2001 From: Johan Peltenburg Date: Tue, 12 Jan 2021 09:30:21 +0100 Subject: [PATCH 8/9] Add simpler primitive map example This matches the fletcher_opae example that we will use for testing --- codegen/test/primmap_simple/.gitignore | 11 +++++++++++ codegen/test/primmap_simple/generate-input.py | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 codegen/test/primmap_simple/.gitignore create mode 100644 codegen/test/primmap_simple/generate-input.py diff --git a/codegen/test/primmap_simple/.gitignore b/codegen/test/primmap_simple/.gitignore new file mode 100644 index 000000000..5182ef45c --- /dev/null +++ b/codegen/test/primmap_simple/.gitignore @@ -0,0 +1,11 @@ +work +vsim.wlf +transcript +dot/ +vhdmmio-doc/ +*.gen.* +fletchgen.mmio.yaml +memory.srec +vhdmmio.log +in.rb +out.as diff --git a/codegen/test/primmap_simple/generate-input.py b/codegen/test/primmap_simple/generate-input.py new file mode 100644 index 000000000..773274301 --- /dev/null +++ b/codegen/test/primmap_simple/generate-input.py @@ -0,0 +1,18 @@ +import pyarrow as pa + +# Input schema and batch +in_schema = pa.schema([pa.field('number', pa.int64(), nullable=False)]) +in_schema = in_schema.with_metadata({b'fletcher_mode': b'read', + b'fletcher_name': b'in'}) +in_data = [pa.array([1, -3, 3, -7])] +in_batch = pa.RecordBatch.from_arrays(in_data, schema=in_schema) +# Create an Arrow RecordBatchFileWriter. +writer = pa.RecordBatchFileWriter('in.rb', in_schema) +writer.write(in_batch) +writer.close() + +# Output schema and batch +out_schema = pa.schema([pa.field('number', pa.int64(), nullable=False)]) +out_schema = out_schema.with_metadata({b'fletcher_mode': b'write', + b'fletcher_name': b'out'}) +pa.output_stream('out.as').write(out_schema.serialize()) From 82daca514c48c6d2ab0b6d539b2471ebe8e644ec Mon Sep 17 00:00:00 2001 From: Johan Peltenburg Date: Tue, 12 Jan 2021 13:14:06 +0100 Subject: [PATCH 9/9] Add missing assignments to AxiWriteConverter --- hardware/axi/AxiWriteConverter.vhd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hardware/axi/AxiWriteConverter.vhd b/hardware/axi/AxiWriteConverter.vhd index 892892723..39054a0b8 100644 --- a/hardware/axi/AxiWriteConverter.vhd +++ b/hardware/axi/AxiWriteConverter.vhd @@ -262,6 +262,7 @@ begin int_slv_bus_wreq_ready <= int_m_axi_awready; int_m_axi_awaddr <= int_slv_bus_wreq_addr; int_m_axi_awlen <= slv(resize(u(int_slv_bus_wreq_len) - 1, MASTER_LEN_WIDTH)); + int_m_axi_awuser(0) <= int_slv_bus_wreq_last; int_m_axi_wvalid <= int_slv_bus_wdat_valid; int_slv_bus_wdat_ready <= int_m_axi_wready; @@ -295,6 +296,7 @@ begin int_m_axi_awaddr <= buf_slv_wreq_addr; -- Convert to AXI spec: int_m_axi_awlen <= slv(resize(u(buf_slv_wreq_len) - 1, MASTER_LEN_WIDTH)); + int_m_axi_awuser(0) <= buf_slv_wreq_last; ----------------------------------------------------------------------------- -- Write Data channel ----------------------------------------------------------------------------- @@ -613,4 +615,3 @@ begin end architecture rtl; -