From 63138d58d285cc52573669cf8630363cf673c660 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 14 Mar 2018 17:04:15 -0700 Subject: [PATCH 01/37] Allow dontcares in configuration base addresses In theory will remove the requirement that the base address be passed down the hierarchy to every module that instantiates AxiLiteCrossbar --- axi/rtl/AxiLiteCrossbar.vhd | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/axi/rtl/AxiLiteCrossbar.vhd b/axi/rtl/AxiLiteCrossbar.vhd index 9f486a43cf..21381904a5 100644 --- a/axi/rtl/AxiLiteCrossbar.vhd +++ b/axi/rtl/AxiLiteCrossbar.vhd @@ -2,7 +2,7 @@ -- File : AxiLiteCrossbar.vhd -- Company : SLAC National Accelerator Laboratory -- Created : 2013-09-24 --- Last update: 2017-11-13 +-- Last update: 2018-03-14 ------------------------------------------------------------------------------- -- Description: Wrapper around Xilinx generated Main AXI Crossbar for HPS Front End ------------------------------------------------------------------------------- @@ -173,9 +173,13 @@ begin for m in MASTERS_CONFIG_G'range loop -- Check for address match - if (sAxiWriteMasters(s).awaddr(31 downto MASTERS_CONFIG_G(m).addrBits) = - MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits) and - MASTERS_CONFIG_G(m).connectivity(s) = '1') then + if ( + std_match( -- Use std_match to allow dontcares ('-') + sAxiWriteMasters(s).awaddr(31 downto MASTERS_CONFIG_G(m).addrBits), + MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits)) + and ( + MASTERS_CONFIG_G(m).connectivity(s) = '1')) + then v.slave(s).wrReqs(m) := '1'; v.slave(s).wrReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); -- print("AxiLiteCrossbar: Slave " & str(s) & " reqd Master " & str(m) & " Write addr " & hstr(sAxiWriteMasters(s).awaddr)); @@ -237,9 +241,13 @@ begin if (sAxiReadMasters(s).arvalid = '1') then for m in MASTERS_CONFIG_G'range loop -- Check for address match - if (sAxiReadMasters(s).araddr(31 downto MASTERS_CONFIG_G(m).addrBits) = - MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits) and - MASTERS_CONFIG_G(m).connectivity(s) = '1') then + if ( + std_match( -- Use std_match to allow dontcares ('-') + sAxiReadMasters(s).araddr(31 downto MASTERS_CONFIG_G(m).addrBits), + MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits)) + and ( + MASTERS_CONFIG_G(m).connectivity(s) = '1')) + then v.slave(s).rdReqs(m) := '1'; v.slave(s).rdReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); end if; From efbb70d9d17407b4a9a2eee8354400d3f67d7e8b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 8 Feb 2019 16:12:57 -0800 Subject: [PATCH 02/37] depreciating lastByteCnt and replacing with WIDTH for SW performance improvement --- protocols/batcher/rtl/AxiStreamBatcher.vhd | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcher.vhd b/protocols/batcher/rtl/AxiStreamBatcher.vhd index 2680e897ec..008b15ea1d 100644 --- a/protocols/batcher/rtl/AxiStreamBatcher.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcher.vhd @@ -52,6 +52,8 @@ architecture rtl of AxiStreamBatcher is constant AXIS_WORD_SIZE_C : positive := AXIS_CONFIG_G.TDATA_BYTES_C; -- Units of bytes + constant WIDTH_C : slv(3 downto 0) := toSlv(log2(AXIS_WORD_SIZE_C/2), 4); + type StateType is ( HEADER_S, SUB_FRAME_S, @@ -74,7 +76,6 @@ architecture rtl of AxiStreamBatcher is tDest : slv(7 downto 0); tUserFirst : slv(7 downto 0); tUserLast : slv(7 downto 0); - lastByteCnt : slv(7 downto 0); chunkCnt : natural range 0 to 3; rxSlave : AxiStreamSlaveType; txMaster : AxiStreamMasterType; @@ -95,7 +96,6 @@ architecture rtl of AxiStreamBatcher is tDest => (others => '0'), tUserFirst => (others => '0'), tUserLast => (others => '0'), - lastByteCnt => (others => '0'), chunkCnt => 1, rxSlave => AXI_STREAM_SLAVE_INIT_C, txMaster => AXI_STREAM_MASTER_INIT_C, @@ -208,7 +208,7 @@ begin -- Send the super-frame header v.txMaster.tValid := '1'; v.txMaster.tData(3 downto 0) := x"1"; -- Version = 0x1 - v.txMaster.tData(7 downto 4) := toSlv(log2(AXIS_WORD_SIZE_C/2), 4); + v.txMaster.tData(7 downto 4) := WIDTH_C; v.txMaster.tData(15 downto 8) := r.seqCnt; v.txMaster.tData(127 downto 16) := (others => '0'); ssiSetUserSof(AXIS_CONFIG_G, v.txMaster, '1'); @@ -239,8 +239,6 @@ begin end if; -- Check for last transaction in sub-frame if (rxMaster.tLast = '1') then - -- Get the number of valid bytes in the last transaction of the sub-frame - v.lastByteCnt := toSlv(getTKeep(rxMaster.tKeep, AXIS_CONFIG_G), 8); -- Increment the sub-frame byte counter v.subByteCnt := r.subByteCnt + getTKeep(rxMaster.tKeep, AXIS_CONFIG_G); -- Sample the meta data @@ -265,7 +263,7 @@ begin v.txMaster.tData(39 downto 32) := r.tDest; v.txMaster.tData(47 downto 40) := r.tUserFirst; v.txMaster.tData(55 downto 48) := r.tUserLast; - v.txMaster.tData(63 downto 56) := r.lastByteCnt; + v.txMaster.tData(59 downto 56) := WIDTH_C; -- Reset the counter v.subByteCnt := (others => '0'); -- Check the AXIS width From a319c26ce4c3183f43073f529f54841c5c683ad8 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 15 Feb 2019 13:07:29 -0800 Subject: [PATCH 03/37] Use numeric_std package --- axi/axi-lite/rtl/AxiLiteCrossbar.vhd | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd index 055eee907f..371f50729c 100644 --- a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd +++ b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd @@ -15,8 +15,8 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + use work.StdRtlPkg.all; use work.AxiLitePkg.all; use work.ArbiterPkg.all; @@ -179,7 +179,7 @@ begin MASTERS_CONFIG_G(m).connectivity(s) = '1')) then v.slave(s).wrReqs(m) := '1'; - v.slave(s).wrReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); + v.slave(s).wrReqNum := slv(to_unsigned(m, REQ_NUM_SIZE_C)); -- print("AxiLiteCrossbar: Slave " & str(s) & " reqd Master " & str(m) & " Write addr " & hstr(sAxiWriteMasters(s).awaddr)); end if; end loop; @@ -247,7 +247,7 @@ begin MASTERS_CONFIG_G(m).connectivity(s) = '1')) then v.slave(s).rdReqs(m) := '1'; - v.slave(s).rdReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); + v.slave(s).rdReqNum := slv(to_unsigned(m, REQ_NUM_SIZE_C)); end if; end loop; @@ -328,7 +328,7 @@ begin -- busses to this master's outputs. if (r.master(m).wrValid = '1') then v.master(m).wrAcks := r.master(m).wrAcks; - v.mAxiWriteMasters(m) := sAxiWriteMasters(conv_integer(r.master(m).wrAckNum)); + v.mAxiWriteMasters(m) := sAxiWriteMasters(to_integer(unsigned(r.master(m).wrAckNum))); v.master(m).wrState := M_WAIT_READYS_S; end if; @@ -351,7 +351,7 @@ begin when M_WAIT_REQ_FALL_S => -- When slave side deasserts request, clear ack and valid and start waiting for next -- request - if (mWrReqs(conv_integer(r.master(m).wrAckNum)) = '0') then + if (mWrReqs(to_integer(unsigned(r.master(m).wrAckNum))) = '0') then v.master(m).wrState := M_WAIT_REQ_S; v.master(m).wrAcks := (others => '0'); v.master(m).wrValid := '0'; @@ -384,7 +384,7 @@ begin -- busses to this master's outputs. if (r.master(m).rdValid = '1') then v.master(m).rdAcks := r.master(m).rdAcks; - v.mAxiReadMasters(m) := sAxiReadMasters(conv_integer(r.master(m).rdAckNum)); + v.mAxiReadMasters(m) := sAxiReadMasters(to_integer(unsigned(r.master(m).rdAckNum))); v.master(m).rdState := M_WAIT_READYS_S; end if; @@ -404,7 +404,7 @@ begin when M_WAIT_REQ_FALL_S => -- When slave side deasserts request, clear ack and valid and start waiting for next -- request - if (mRdReqs(conv_integer(r.master(m).rdAckNum)) = '0') then + if (mRdReqs(to_integer(unsigned(r.master(m).rdAckNum))) = '0') then v.master(m).rdState := M_WAIT_REQ_S; v.master(m).rdAcks := (others => '0'); v.master(m).rdValid := '0'; From 93e120377199f5282032aff91bd1d7c52f26bf79 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 15 Feb 2019 13:39:55 -0800 Subject: [PATCH 04/37] Fix unsigned compares with integer --- axi/axi-lite/rtl/AxiLiteCrossbar.vhd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd index 371f50729c..a852c90572 100644 --- a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd +++ b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd @@ -205,7 +205,7 @@ begin -- Transaction is acked when S_ACK_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (r.slave(s).wrReqNum = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then + if (unsigned(r.slave(s).wrReqNum) = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then v.sAxiWriteSlaves(s).awready := '1'; v.sAxiWriteSlaves(s).wready := '1'; v.slave(s).wrState := S_TXN_S; @@ -272,7 +272,7 @@ begin -- Transaction is acked when S_ACK_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (r.slave(s).rdReqNum = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then + if (unsigned(r.slave(s).rdReqNum) = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then v.sAxiReadSlaves(s).arready := '1'; v.slave(s).rdState := S_TXN_S; end if; @@ -281,7 +281,7 @@ begin -- Transaction in progress when S_TXN_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (r.slave(s).rdReqNum = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then + if (unsigned(r.slave(s).rdReqNum = m) and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then -- Forward read response v.sAxiReadSlaves(s).rresp := mAxiReadSlaves(m).rresp; From 520b93426c515fd9c1e790546d5b0255fb2558e7 Mon Sep 17 00:00:00 2001 From: Leonid Sapozhnikov Date: Fri, 15 Feb 2019 14:21:27 -0800 Subject: [PATCH 05/37] Fix issues with unsigned compares --- axi/axi-lite/rtl/AxiLiteCrossbar.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd index a852c90572..a7d1ad17c0 100644 --- a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd +++ b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd @@ -215,7 +215,7 @@ begin -- Transaction in progress when S_TXN_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (r.slave(s).wrReqNum = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then + if (unsigned(r.slave(s).wrReqNum) = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then -- Forward write response v.sAxiWriteSlaves(s).bresp := mAxiWriteSlaves(m).bresp; @@ -281,7 +281,7 @@ begin -- Transaction in progress when S_TXN_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (unsigned(r.slave(s).rdReqNum = m) and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then + if (unsigned(r.slave(s).rdReqNum) = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then -- Forward read response v.sAxiReadSlaves(s).rresp := mAxiReadSlaves(m).rresp; From cd36048d6b2388caa9829392cb7491d0c085e80b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 11:44:06 -0800 Subject: [PATCH 06/37] exposing ILEAVE_ON_NOTVALID_G & ILEAVE_REARB_G --- axi/axi-stream/rtl/AxiStreamTap.vhd | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamTap.vhd b/axi/axi-stream/rtl/AxiStreamTap.vhd index ce93ad7d5b..dd99c9edce 100644 --- a/axi/axi-stream/rtl/AxiStreamTap.vhd +++ b/axi/axi-stream/rtl/AxiStreamTap.vhd @@ -23,17 +23,19 @@ use work.AxiStreamPkg.all; entity AxiStreamTap is generic ( - TPD_G : time := 1 ns; - PIPE_STAGES_G : integer range 0 to 16 := 0; - TAP_DEST_G : integer range 0 to 255 := 0); + TPD_G : time := 1 ns; + TAP_DEST_G : natural range 0 to 255 := 0; + PIPE_STAGES_G : natural range 0 to 16 := 0; + ILEAVE_ON_NOTVALID_G : boolean := false; + ILEAVE_REARB_G : natural := 0); port ( - -- Slave + -- Slave Interface sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; - -- Masters + -- Master Interface mAxisMaster : out AxiStreamMasterType; mAxisSlave : in AxiStreamSlaveType; - -- Tap + -- Tap Interface tmAxisMaster : out AxiStreamMasterType; tmAxisSlave : in AxiStreamSlaveType; tsAxisMaster : in AxiStreamMasterType; @@ -45,15 +47,15 @@ end AxiStreamTap; architecture structure of AxiStreamTap is - constant ROUTES_C : Slv8Array := (0 => "--------", - 1 => toSlv(TAP_DEST_G,8)); + constant ROUTES_C : Slv8Array := (0 => "--------", + 1 => toSlv(TAP_DEST_G, 8)); - signal iAxisMaster : AxiStreamMasterType; - signal iAxisSlave : AxiStreamSlaveType; + signal iAxisMaster : AxiStreamMasterType; + signal iAxisSlave : AxiStreamSlaveType; begin - U_DeMux: entity work.AxiStreamDeMux + U_DeMux : entity work.AxiStreamDeMux generic map ( TPD_G => TPD_G, PIPE_STAGES_G => PIPE_STAGES_G, @@ -70,15 +72,16 @@ begin axisClk => axisClk, axisRst => axisRst); - U_Mux: entity work.AxiStreamMux + U_Mux : entity work.AxiStreamMux generic map ( - TPD_G => TPD_G, - PIPE_STAGES_G => PIPE_STAGES_G, - NUM_SLAVES_G => 2, - MODE_G => "ROUTED", - TDEST_ROUTES_G => ROUTES_C, - ILEAVE_EN_G => true, - ILEAVE_REARB_G => 0) + TPD_G => TPD_G, + PIPE_STAGES_G => PIPE_STAGES_G, + NUM_SLAVES_G => 2, + MODE_G => "ROUTED", + TDEST_ROUTES_G => ROUTES_C, + ILEAVE_EN_G => true, + ILEAVE_ON_NOTVALID_G => ILEAVE_ON_NOTVALID_G, + ILEAVE_REARB_G => ILEAVE_REARB_G) port map ( axisClk => axisClk, axisRst => axisRst, From 2e44155ca88d96ca01667ba5497c720a855ba527 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 11:45:29 -0800 Subject: [PATCH 07/37] adding optional timeout feature to AxiStreamBatcherEventBuilder --- .../rtl/AxiStreamBatcherEventBuilder.vhd | 126 +++++++++++++----- 1 file changed, 96 insertions(+), 30 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd index 46611027f5..c0c067b0fa 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd @@ -19,6 +19,7 @@ use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use work.StdRtlPkg.all; +use work.AxiLitePkg.all; use work.AxiStreamPkg.all; use work.SsiPkg.all; @@ -45,13 +46,18 @@ entity AxiStreamBatcherEventBuilder is OUTPUT_PIPE_STAGES_G : natural := 0); port ( -- Clock and Reset - axisClk : in sl; - axisRst : in sl; + axisClk : in sl; + axisRst : in sl; + -- AXI-Lite Interface + axilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + axilWriteSlave : out AxiLiteWriteSlaveType; -- AXIS Interfaces - sAxisMasters : in AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); - sAxisSlaves : out AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType); + sAxisMasters : in AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); + sAxisSlaves : out AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamBatcherEventBuilder; architecture rtl of AxiStreamBatcherEventBuilder is @@ -63,23 +69,31 @@ architecture rtl of AxiStreamBatcherEventBuilder is MOVE_S); type RegType is record - ready : sl; - maxSubFrames : slv(15 downto 0); - accept : slv(NUM_SLAVES_G-1 downto 0); - index : natural range 0 to NUM_SLAVES_G-1; - rxSlaves : AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); - txMaster : AxiStreamMasterType; - state : StateType; + ready : sl; + maxSubFrames : slv(15 downto 0); + timer : slv(31 downto 0); + timeout : slv(31 downto 0); + accept : slv(NUM_SLAVES_G-1 downto 0); + index : natural range 0 to NUM_SLAVES_G-1; + axilReadSlave : AxiLiteReadSlaveType; + axilWriteSlave : AxiLiteWriteSlaveType; + rxSlaves : AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); + txMaster : AxiStreamMasterType; + state : StateType; end record RegType; constant REG_INIT_C : RegType := ( - ready => '0', - maxSubFrames => toSlv(NUM_SLAVES_G, 16), - accept => (others => '0'), - index => 0, - rxSlaves => (others => AXI_STREAM_SLAVE_INIT_C), - txMaster => AXI_STREAM_MASTER_INIT_C, - state => IDLE_S); + ready => '0', + maxSubFrames => toSlv(NUM_SLAVES_G, 16), + timer => (others => '0'), + timeout => (others => '0'), + accept => (others => '0'), + index => 0, + axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, + axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C, + rxSlaves => (others => AXI_STREAM_SLAVE_INIT_C), + txMaster => AXI_STREAM_MASTER_INIT_C, + state => IDLE_S); signal r : RegType := REG_INIT_C; signal rin : RegType; @@ -140,13 +154,30 @@ begin mAxisSlave => rxSlaves(i)); end generate GEN_VEC; - comb : process (axisRst, batcherIdle, r, rxMasters, txSlave) is - variable v : RegType; - variable i : natural; + comb : process (axilReadMaster, axilWriteMaster, axisRst, batcherIdle, r, + rxMasters, txSlave) is + variable v : RegType; + variable axilEp : AxiLiteEndPointType; + variable i : natural; begin -- Latch the current value v := r; + -- Determine the transaction type + axiSlaveWaitTxn(axilEp, axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave); + + -- Map the registers + axiSlaveRegister(axilEp, x"00", 0, v.timeout); + + -- Closeout the transaction + axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); + + -- Check for change in configuration + if (r.timeout /= v.timeout) then + -- Reset the timer + v.timer := (others => '0'); + end if; + -- Reset the flow control strobes for i in (NUM_SLAVES_G-1) downto 0 loop v.rxSlaves(i).tReady := '0'; @@ -161,7 +192,9 @@ begin when IDLE_S => -- Loop through RX channels v.ready := '1'; + for i in (NUM_SLAVES_G-1) downto 0 loop + -- Check if no data if (rxMasters(i).tValid = '0') then -- Reset the flag @@ -179,46 +212,79 @@ begin end if; end if; end loop; + + -- Check if using timer + if (r.timeout /= 0) then + -- Check if 1 of the channels are ready + if (r.accept /= 0) then + -- Check for timeout + if (r.timer = r.timeout) then + -- Set the flag + v.ready := '1'; + else + -- Increment the counter + v.timer := r.timer + 1; + end if; + end if; + end if; + -- Check if ready to move data if (batcherIdle = '1') and (r.ready = '1') then + -- Reset the flag - v.ready := '0'; + v.ready := '0'; + + -- Reset the counter + v.timer := (others => '0'); + -- Set the sub-frame count v.maxSubFrames := resize(onesCount(r.accept), 16); + -- Next state - v.state := MOVE_S; + v.state := MOVE_S; + end if; ---------------------------------------------------------------------- when MOVE_S => -- Check if ready to move data if (rxMasters(r.index).tValid = '1') and (v.txMaster.tValid = '0') then + -- Move the data v.rxSlaves(r.index).tReady := '1'; v.txMaster := rxMasters(r.index); + -- Only forward the non-NULL frames - v.txMaster.tValid := r.accept(r.index); + v.txMaster.tValid := r.accept(r.index); + -- Check for the last transfer if (rxMasters(r.index).tLast = '1') then + -- Check for last channel if (r.index = NUM_SLAVES_G-1) then + -- Reset the counter - v.index := 0; + v.index := 0; + -- Reset the accept field (makes it easier to look at simulation) v.accept := (others => '0'); + -- Next state - v.state := IDLE_S; + v.state := IDLE_S; else -- Increment the counter v.index := r.index + 1; end if; + end if; end if; ---------------------------------------------------------------------- end case; -- Outputs - rxSlaves <= v.rxSlaves; - txMaster <= r.txMaster; + rxSlaves <= v.rxSlaves; + txMaster <= r.txMaster; + axilWriteSlave <= r.axilWriteSlave; + axilReadSlave <= r.axilReadSlave; -- Reset if (axisRst = '1') then From 5e1d6d981cfef90cef181ef2de20b471c27d9753 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 12:58:54 -0800 Subject: [PATCH 08/37] removing unused sim source code --- axi/axi-stream/tb/rogue_tb.vhd | 86 --------- protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd | 171 ------------------ 2 files changed, 257 deletions(-) delete mode 100644 axi/axi-stream/tb/rogue_tb.vhd delete mode 100644 protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd diff --git a/axi/axi-stream/tb/rogue_tb.vhd b/axi/axi-stream/tb/rogue_tb.vhd deleted file mode 100644 index 677402fd01..0000000000 --- a/axi/axi-stream/tb/rogue_tb.vhd +++ /dev/null @@ -1,86 +0,0 @@ -------------------------------------------------------------------------------- --- File : rogue_tb.vhd --- Company : SLAC National Accelerator Laboratory -------------------------------------------------------------------------------- --- Description: Simulation Testbed for ROGUE module -------------------------------------------------------------------------------- --- This file is part of 'SLAC Firmware Standard Library'. --- It is subject to the license terms in the LICENSE.txt file found in the --- top-level directory of this distribution and at: --- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. --- No part of 'SLAC Firmware Standard Library', including this file, --- may be copied, modified, propagated, or distributed except according to --- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- - -LIBRARY ieee; -USE work.ALL; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; -Library unisim; -use unisim.vcomponents.all; - -use work.StdRtlPkg.all; -use work.AxiStreamPkg.all; - -entity rogue_tb is end rogue_tb; - --- Define architecture -architecture rogue_tb of rogue_tb is - - constant TPD_C : time := 1 ns; - - signal axiClk : sl; - signal axiClkRst : sl; - signal sAxisMaster : AxiStreamMasterType; - signal sAxisSlave : AxiStreamSlaveType; - signal mAxisMaster : AxiStreamMasterType; - signal mAxisSlave : AxiStreamSlaveType; - signal opCode : slv(7 downto 0); - signal opCodeEn : sl; - signal remData : slv(7 downto 0); - -begin - - process begin - axiClk <= '1'; - wait for 5 ns; - axiClk <= '0'; - wait for 5 ns; - end process; - - process begin - axiClkRst <= '1'; - wait for (100 ns); - axiClkRst <= '0'; - wait; - end process; - - U_RogueSim: entity work.RogueStreamSimWrap - generic map ( - TPD_G => 1 ns, - DEST_ID_G => 20, - COMMON_MASTER_CLK_G => true, - COMMON_SLAVE_CLK_G => true, - AXIS_CONFIG_G => AXI_STREAM_CONFIG_INIT_C) - port map ( - clk => axiClk, - rst => axiClkRst, - sAxisClk => axiClk, - sAxisRst => axiClkRst, - sAxisMaster => sAxisMaster, - sAxisSlave => sAxisSlave, - mAxisClk => axiClk, - mAxisRst => axiClkRst, - mAxisMaster => mAxisMaster, - mAxisSlave => mAxisSlave, - opCode => opCode, - opCodeEn => opCodeEn, - remData => remData); - - sAxisMaster <= mAxisMaster; - mAxisSlave <= sAxisSlave; - -end rogue_tb; - diff --git a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd deleted file mode 100644 index 9717822fa5..0000000000 --- a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd +++ /dev/null @@ -1,171 +0,0 @@ -------------------------------------------------------------------------------- --- File : RoguePgp2bSim.vhd --- Company : SLAC National Accelerator Laboratory -------------------------------------------------------------------------------- --- Description: Wrapper on RogueStreamSim to simulate a PGP lane with 4 --- virtual channels -------------------------------------------------------------------------------- --- This file is part of 'SLAC Firmware Standard Library'. --- It is subject to the license terms in the LICENSE.txt file found in the --- top-level directory of this distribution and at: --- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. --- No part of 'SLAC Firmware Standard Library', including this file, --- may be copied, modified, propagated, or distributed except according to --- the terms contained in the LICENSE.txt file. -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -library unisim; -use unisim.vcomponents.all; - -use work.StdRtlPkg.all; -use work.AxiStreamPkg.all; -use work.Pgp2bPkg.all; - - -entity RoguePgp2bSim is - - generic ( - TPD_G : time := 1 ns; - FIXED_LAT_G : boolean := false; - RX_CLK_PERIOD_G : real := 8.0e-9; - USER_ID_G : integer range 0 to 100 := 1; - NUM_VC_EN_G : integer range 1 to 4 := 4); - - port ( - refClkP : in sl; - refClkM : in sl; - - pgpTxClk : out sl; - pgpTxRst : out sl; - pgpTxIn : in Pgp2bTxInType := PGP2B_TX_IN_INIT_C; - pgpTxOut : out Pgp2bTxOutType; - pgpTxMasters : in AxiStreamMasterArray(NUM_VC_EN_G-1 downto 0); - pgpTxSlaves : out AxiStreamSlaveArray(NUM_VC_EN_G-1 downto 0); - - pgpRxClk : out sl := '0'; -- Used in FIXED_LAT mode - pgpRxRst : out sl := '0'; - pgpRxIn : in Pgp2bRxInType := PGP2B_RX_IN_INIT_C; - pgpRxOut : out Pgp2bRxOutType; - pgpRxMasters : out AxiStreamMasterArray(NUM_VC_EN_G-1 downto 0); - pgpRxSlaves : in AxiStreamSlaveArray(NUM_VC_EN_G-1 downto 0)); - -end entity RoguePgp2bSim; - -architecture sim of RoguePgp2bSim is - - constant RX_CLK_PERIOD_C : time := RX_CLK_PERIOD_G * (1000 ms); - - signal pgpClk : sl := '0'; - signal pgpRst : sl := '0'; - - signal rxClk : sl := '0'; - signal rxRst : sl := '0'; - -begin - - IBUFDS_GTE2_Inst : IBUFGDS - port map ( - I => refClkP, - IB => refClkM, - O => pgpClk); - - PwrUpRst_Inst : entity work.PwrUpRst - generic map ( - TPD_G => TPD_G, - IN_POLARITY_G => '1', - OUT_POLARITY_G => '1', - DURATION_G => 50) - port map ( - clk => pgpClk, - rstOut => pgpRst); - - pgpTxClk <= pgpClk; - pgpTxRst <= pgpRst; - - - -- pgpRxClk is same as pgpTxClk if not in fixed lat mode - NORMAL : if (not FIXED_LAT_G) generate - pgpRxClk <= pgpClk; - pgpRxRst <= pgpRst; - rxClk <= pgpClk; - end generate NORMAL; - - -- If fixed late, create an internal clock to emulate recovered clock - FIXED_LAT : if (FIXED_LAT_G) generate - U_ClkRst_1 : entity work.ClkRst - generic map ( - CLK_PERIOD_G => RX_CLK_PERIOD_C, - CLK_DELAY_G => 0.14159 ns, - RST_HOLD_TIME_G => 30 ns, - SYNC_RESET_G => true) - port map ( - clkP => rxClk, -- [out] - rst => rxRst); -- [out] - - pgpRxClk <= rxClk; - pgpRxRst <= rxRst; - end generate FIXED_LAT; - - GEN_AXIS_LANE : for i in NUM_VC_EN_G-1 downto 0 generate - U_RogueStreamSimWrap_PGP_VC : entity work.RogueStreamSimWrap - generic map ( - TPD_G => TPD_G, - DEST_ID_G => i, - USER_ID_G => USER_ID_G, - AXIS_CONFIG_G => SSI_PGP2B_CONFIG_C) - port map ( - clk => pgpClk, -- [in] - rst => pgpRst, -- [in] - sAxisClk => pgpClk, -- [in] - sAxisRst => pgpRst, -- [in] - sAxisMaster => pgpTxMasters(i), -- [in] - sAxisSlave => pgpTxSlaves(i), -- [out] - mAxisClk => rxClk, -- [in] - mAxisRst => rxRst, -- [in] - mAxisMaster => pgpRxMasters(i), -- [out] - mAxisSlave => pgpRxSlaves(i)); -- [in] - end generate GEN_AXIS_LANE; - - U_RogueStreamSimWrap_OPCODE : entity work.RogueStreamSimWrap - generic map ( - TPD_G => TPD_G, - DEST_ID_G => 4, - AXIS_CONFIG_G => SSI_PGP2B_CONFIG_C) - port map ( - clk => pgpClk, -- [in] - rst => pgpRst, -- [in] - sAxisClk => pgpClk, -- [in] - sAxisRst => pgpRst, -- [in] - sAxisMaster => AXI_STREAM_MASTER_INIT_C, -- [in] - sAxisSlave => open, -- [out] - mAxisClk => rxClk, -- [in] - mAxisRst => rxRst, -- [in] - mAxisMaster => open, -- [out] - mAxisSlave => AXI_STREAM_SLAVE_FORCE_C, -- [in] - opCode => pgpRxOut.opCode, -- [out] - opCodeEn => pgpRxOut.opCodeEn, -- [out] - remData => pgpRxOut.remLinkData); -- [out] - - pgpRxOut.phyRxReady <= '1'; - pgpRxOut.linkReady <= '1'; - pgpRxOut.linkPolarity <= (others => '0'); - pgpRxOut.frameRx <= '0'; - pgpRxOut.frameRxErr <= '0'; - pgpRxOut.linkDown <= '0'; - pgpRxOut.linkError <= '0'; - pgpRxOut.remLinkReady <= '1'; - pgpRxOut.remOverflow <= (others => '0'); - pgpRxOut.remPause <= (others => '0'); - - pgpTxOut.locOverflow <= (others => '0'); - pgpTxOut.locPause <= (others => '0'); - pgpTxOut.phyTxReady <= '1'; - pgpTxOut.linkReady <= '1'; - pgpTxOut.frameTx <= '0'; - pgpTxOut.frameTxErr <= '0'; -end architecture sim; From 6e294dbdcb4162fe2a2cabdf60e3948fc2085ef8 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 13:16:49 -0800 Subject: [PATCH 09/37] adding 256 TDEST support to RogueTcpStreamWrap --- axi/simlink/sim/RogueSideBandWrap.vhd | 2 +- axi/simlink/sim/RogueTcpMemoryWrap.vhd | 2 +- axi/simlink/sim/RogueTcpStreamWrap.vhd | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/axi/simlink/sim/RogueSideBandWrap.vhd b/axi/simlink/sim/RogueSideBandWrap.vhd index 2cbf091de5..e7ed270657 100755 --- a/axi/simlink/sim/RogueSideBandWrap.vhd +++ b/axi/simlink/sim/RogueSideBandWrap.vhd @@ -23,7 +23,7 @@ use work.AxiStreamPkg.all; entity RogueSideBandWrap is generic ( TPD_G : time := 1 ns; - PORT_NUM_G : integer range 0 to 65535 := 1 + PORT_NUM_G : natural range 0 to 65535 := 1 ); port ( sysClk : in sl; diff --git a/axi/simlink/sim/RogueTcpMemoryWrap.vhd b/axi/simlink/sim/RogueTcpMemoryWrap.vhd index 662a3595c6..69cab2f8ae 100755 --- a/axi/simlink/sim/RogueTcpMemoryWrap.vhd +++ b/axi/simlink/sim/RogueTcpMemoryWrap.vhd @@ -24,7 +24,7 @@ use work.AxiLitePkg.all; entity RogueTcpMemoryWrap is generic ( TPD_G : time := 1 ns; - PORT_NUM_G : integer range 0 to 65535 := 1 + PORT_NUM_G : natural range 0 to 65535 := 1 ); port ( axiClk : in sl; diff --git a/axi/simlink/sim/RogueTcpStreamWrap.vhd b/axi/simlink/sim/RogueTcpStreamWrap.vhd index 2e571652d5..9d73cbb0cb 100755 --- a/axi/simlink/sim/RogueTcpStreamWrap.vhd +++ b/axi/simlink/sim/RogueTcpStreamWrap.vhd @@ -23,9 +23,9 @@ use work.AxiStreamPkg.all; entity RogueTcpStreamWrap is generic ( TPD_G : time := 1 ns; - PORT_NUM_G : integer range 0 to 65535 := 1; + PORT_NUM_G : natural range 0 to 65535 := 1; SSI_EN_G : boolean := true; - CHAN_COUNT_G : integer range 1 to 32 := 1; + CHAN_COUNT_G : positive range 1 to 256 := 1; COMMON_MASTER_CLK_G : boolean := false; COMMON_SLAVE_CLK_G : boolean := false; AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C @@ -75,6 +75,9 @@ architecture RogueTcpStreamWrap of RogueTcpStreamWrap is begin + assert (PORT_NUM_G + 2*(CHAN_COUNT_G-1) <= 65535) + report "PORT_NUM_G + 2*(CHAN_COUNT_G-1) must less than or equal to 65535" severity failure; + ------------------------------------ -- Inbound Demux ------------------------------------ From 2fa21d29038fc954e42217cd82193af2f64e8d06 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 13:26:23 -0800 Subject: [PATCH 10/37] upgrading protocols/pgp/pgp3 to RogueTcpStreamWrap --- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 13 +++-- .../pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd | 58 +++++++++---------- .../pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd | 56 +++++++++--------- .../pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd | 54 ++++++++--------- 4 files changed, 91 insertions(+), 90 deletions(-) diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index 104f0b8191..0fcb0cfd18 100644 --- a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd +++ b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd @@ -28,9 +28,9 @@ use unisim.vcomponents.all; entity RoguePgp3Sim is generic ( - TPD_G : time := 1 ns; - USER_ID_G : integer range 0 to 100 := 1; - NUM_VC_G : integer range 1 to 16 := 4); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 0 to 65535 := 1; + NUM_VC_G : integer range 1 to 16 := 4); port ( -- GT Ports pgpRefClk : in sl; @@ -91,11 +91,12 @@ begin rstOut => rst); GEN_VEC : for i in NUM_VC_G-1 downto 0 generate - U_PGP_VC : entity work.RogueStreamSimWrap + U_PGP_VC : entity work.RogueTcpStreamWrap generic map ( TPD_G => TPD_G, - DEST_ID_G => i, - USER_ID_G => USER_ID_G, + PORT_NUM_G => (PORT_NUM_G + i*2), + SSI_EN_G => true, + CHAN_COUNT_G => 1, COMMON_MASTER_CLK_G => true, COMMON_SLAVE_CLK_G => true, AXIS_CONFIG_G => PGP3_AXIS_CONFIG_C) diff --git a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd index d579140a49..c2dcf5bcde 100644 --- a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd +++ b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd @@ -29,32 +29,32 @@ use unisim.vcomponents.all; entity Pgp3GthUsWrapper is generic ( - TPD_G : time := 1 ns; - ROGUE_SIM_EN_G : boolean := false; - ROGUE_SIM_USER_ID_G : integer range 0 to 100 := 1; - NUM_LANES_G : positive range 1 to 4 := 1; - NUM_VC_G : positive range 1 to 16 := 4; - REFCLK_G : boolean := false; -- FALSE: pgpRefClkP/N, TRUE: pgpRefClkIn - RATE_G : string := "10.3125Gbps"; -- or "6.25Gbps" or "3.125Gbps" + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 0 to 65535 := 1; + NUM_LANES_G : positive range 1 to 4 := 1; + NUM_VC_G : positive range 1 to 16 := 4; + REFCLK_G : boolean := false; -- FALSE: pgpRefClkP/N, TRUE: pgpRefClkIn + RATE_G : string := "10.3125Gbps"; -- or "6.25Gbps" or "3.125Gbps" ---------------------------------------------------------------------------------------------- -- PGP Settings ---------------------------------------------------------------------------------------------- - PGP_RX_ENABLE_G : boolean := true; - RX_ALIGN_SLIP_WAIT_G : integer := 32; - PGP_TX_ENABLE_G : boolean := true; - TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell - TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" - TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode - TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; - TX_MUX_ILEAVE_EN_G : boolean := true; - TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := true; - EN_PGP_MON_G : boolean := false; - EN_GTH_DRP_G : boolean := false; - EN_QPLL_DRP_G : boolean := false; - TX_POLARITY_G : slv(3 downto 0) := x"0"; - RX_POLARITY_G : slv(3 downto 0) := x"0"; - AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); - AXIL_CLK_FREQ_G : real := 125.0E+6); + PGP_RX_ENABLE_G : boolean := true; + RX_ALIGN_SLIP_WAIT_G : integer := 32; + PGP_TX_ENABLE_G : boolean := true; + TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell + TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" + TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode + TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; + TX_MUX_ILEAVE_EN_G : boolean := true; + TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := true; + EN_PGP_MON_G : boolean := false; + EN_GTH_DRP_G : boolean := false; + EN_QPLL_DRP_G : boolean := false; + TX_POLARITY_G : slv(3 downto 0) := x"0"; + RX_POLARITY_G : slv(3 downto 0) := x"0"; + AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); + AXIL_CLK_FREQ_G : real := 125.0E+6); port ( -- Stable Clock and Reset stableClk : in sl; -- GT needs a stable clock to "boot up" @@ -65,9 +65,9 @@ entity Pgp3GthUsWrapper is pgpGtRxP : in slv(NUM_LANES_G-1 downto 0); pgpGtRxN : in slv(NUM_LANES_G-1 downto 0); -- GT Clocking - pgpRefClkP : in sl := '0'; -- 156.25 MHz - pgpRefClkN : in sl := '1'; -- 156.25 MHz - pgpRefClkIn : in sl := '0'; -- 156.25 MHz + pgpRefClkP : in sl := '0'; -- 156.25 MHz + pgpRefClkN : in sl := '1'; -- 156.25 MHz + pgpRefClkIn : in sl := '0'; -- 156.25 MHz pgpRefClkOut : out sl; pgpRefClkDiv2Bufg : out sl; -- Clocking @@ -267,9 +267,9 @@ begin GEN_LANE : for i in NUM_LANES_G-1 downto 0 generate U_Rogue : entity work.RoguePgp3Sim generic map( - TPD_G => TPD_G, - USER_ID_G => (ROGUE_SIM_USER_ID_G+i), - NUM_VC_G => NUM_VC_G) + TPD_G => TPD_G, + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + NUM_VC_G => NUM_VC_G) port map( -- GT Ports pgpRefClk => pgpRefClk, diff --git a/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd b/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd index 0908978fb5..83a07311d7 100644 --- a/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd +++ b/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd @@ -28,34 +28,34 @@ use unisim.vcomponents.all; entity Pgp3Gtp7Wrapper is generic ( - TPD_G : time := 1 ns; - ROGUE_SIM_EN_G : boolean := false; - ROGUE_SIM_USER_ID_G : integer range 0 to 100 := 1; - NUM_LANES_G : positive range 1 to 4 := 1; - NUM_VC_G : positive range 1 to 16 := 4; - SPEED_GRADE_G : positive range 1 to 3 := 3; - RATE_G : string := "6.25Gbps"; -- or "3.125Gbps" - REFCLK_TYPE_G : Pgp3RefClkType := PGP3_REFCLK_250_C; - REFCLK_G : boolean := false; -- FALSE: use pgpRefClkP/N, TRUE: use pgpRefClkIn + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 0 to 65535 := 1; + NUM_LANES_G : positive range 1 to 4 := 1; + NUM_VC_G : positive range 1 to 16 := 4; + SPEED_GRADE_G : positive range 1 to 3 := 3; + RATE_G : string := "6.25Gbps"; -- or "3.125Gbps" + REFCLK_TYPE_G : Pgp3RefClkType := PGP3_REFCLK_250_C; + REFCLK_G : boolean := false; -- FALSE: use pgpRefClkP/N, TRUE: use pgpRefClkIn ---------------------------------------------------------------------------------------------- -- PGP Settings ---------------------------------------------------------------------------------------------- - PGP_RX_ENABLE_G : boolean := true; - RX_ALIGN_SLIP_WAIT_G : integer := 32; - PGP_TX_ENABLE_G : boolean := true; - TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell - TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" - TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode - TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; - TX_MUX_ILEAVE_EN_G : boolean := true; - TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := false; - EN_PGP_MON_G : boolean := false; - EN_GTH_DRP_G : boolean := false; - EN_QPLL_DRP_G : boolean := false; - TX_POLARITY_G : slv(3 downto 0) := x"0"; - RX_POLARITY_G : slv(3 downto 0) := x"0"; - AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); - AXIL_CLK_FREQ_G : real := 156.25E+6); + PGP_RX_ENABLE_G : boolean := true; + RX_ALIGN_SLIP_WAIT_G : integer := 32; + PGP_TX_ENABLE_G : boolean := true; + TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell + TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" + TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode + TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; + TX_MUX_ILEAVE_EN_G : boolean := true; + TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := false; + EN_PGP_MON_G : boolean := false; + EN_GTH_DRP_G : boolean := false; + EN_QPLL_DRP_G : boolean := false; + TX_POLARITY_G : slv(3 downto 0) := x"0"; + RX_POLARITY_G : slv(3 downto 0) := x"0"; + AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); + AXIL_CLK_FREQ_G : real := 156.25E+6); port ( -- Stable Clock and Reset stableClk : in sl; -- GT needs a stable clock to "boot up" @@ -392,9 +392,9 @@ begin GEN_LANE : for i in NUM_LANES_G-1 downto 0 generate U_Rogue : entity work.RoguePgp3Sim generic map( - TPD_G => TPD_G, - USER_ID_G => (ROGUE_SIM_USER_ID_G+i), - NUM_VC_G => NUM_VC_G) + TPD_G => TPD_G, + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + NUM_VC_G => NUM_VC_G) port map( -- GT Ports pgpRefClk => pgpRefClk, diff --git a/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd b/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd index 111ae3c496..90a8b7208e 100644 --- a/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd +++ b/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd @@ -28,33 +28,33 @@ use unisim.vcomponents.all; entity Pgp3Gtx7Wrapper is generic ( - TPD_G : time := 1 ns; - ROGUE_SIM_EN_G : boolean := false; - ROGUE_SIM_USER_ID_G : integer range 0 to 100 := 1; - NUM_LANES_G : positive range 1 to 4 := 1; - NUM_VC_G : positive range 1 to 16 := 4; - RATE_G : string := "10.3125Gbps"; -- or "6.25Gbps" or "3.125Gbps" - REFCLK_TYPE_G : Pgp3RefClkType := PGP3_REFCLK_312_C; - REFCLK_G : boolean := false; -- FALSE: use pgpRefClkP/N, TRUE: use pgpRefClkIn + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 0 to 65535 := 1; + NUM_LANES_G : positive range 1 to 4 := 1; + NUM_VC_G : positive range 1 to 16 := 4; + RATE_G : string := "10.3125Gbps"; -- or "6.25Gbps" or "3.125Gbps" + REFCLK_TYPE_G : Pgp3RefClkType := PGP3_REFCLK_312_C; + REFCLK_G : boolean := false; -- FALSE: use pgpRefClkP/N, TRUE: use pgpRefClkIn ---------------------------------------------------------------------------------------------- -- PGP Settings ---------------------------------------------------------------------------------------------- - PGP_RX_ENABLE_G : boolean := true; - RX_ALIGN_SLIP_WAIT_G : integer := 32; - PGP_TX_ENABLE_G : boolean := true; - TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell - TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" - TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode - TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; - TX_MUX_ILEAVE_EN_G : boolean := true; - TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := true; - EN_PGP_MON_G : boolean := false; - EN_GTH_DRP_G : boolean := false; - EN_QPLL_DRP_G : boolean := false; - TX_POLARITY_G : slv(3 downto 0) := x"0"; - RX_POLARITY_G : slv(3 downto 0) := x"0"; - AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); - AXIL_CLK_FREQ_G : real := 156.25E+6); + PGP_RX_ENABLE_G : boolean := true; + RX_ALIGN_SLIP_WAIT_G : integer := 32; + PGP_TX_ENABLE_G : boolean := true; + TX_CELL_WORDS_MAX_G : integer := PGP3_DEFAULT_TX_CELL_WORDS_MAX_C; -- Number of 64-bit words per cell + TX_MUX_MODE_G : string := "INDEXED"; -- Or "ROUTED" + TX_MUX_TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- Only used in ROUTED mode + TX_MUX_TDEST_LOW_G : integer range 0 to 7 := 0; + TX_MUX_ILEAVE_EN_G : boolean := true; + TX_MUX_ILEAVE_ON_NOTVALID_G : boolean := true; + EN_PGP_MON_G : boolean := false; + EN_GTH_DRP_G : boolean := false; + EN_QPLL_DRP_G : boolean := false; + TX_POLARITY_G : slv(3 downto 0) := x"0"; + RX_POLARITY_G : slv(3 downto 0) := x"0"; + AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0'); + AXIL_CLK_FREQ_G : real := 156.25E+6); port ( -- Stable Clock and Reset stableClk : in sl; -- GT needs a stable clock to "boot up" @@ -323,9 +323,9 @@ begin GEN_LANE : for i in NUM_LANES_G-1 downto 0 generate U_Rogue : entity work.RoguePgp3Sim generic map( - TPD_G => TPD_G, - USER_ID_G => (ROGUE_SIM_USER_ID_G+i), - NUM_VC_G => NUM_VC_G) + TPD_G => TPD_G, + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + NUM_VC_G => NUM_VC_G) port map( -- GT Ports pgpRefClk => pgpRefClk, From d4fea8743ec2ae643b7031d2c6c34fa062d51495 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 15:32:07 -0800 Subject: [PATCH 11/37] changing AUTO_RELOAD_TIME_G from real to positive require for CLK of 250 MHz and 10 sec reload time without going out-of-range of integer (2147483647) --- axi/axi-lite/rtl/AxiVersion.vhd | 72 ++++++++++++++------------- axi/axi-lite/rtl/AxiVersionLegacy.vhd | 69 +++++++++++++------------ 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/axi/axi-lite/rtl/AxiVersion.vhd b/axi/axi-lite/rtl/AxiVersion.vhd index 0e960a1ce5..cd4404e29d 100644 --- a/axi/axi-lite/rtl/AxiVersion.vhd +++ b/axi/axi-lite/rtl/AxiVersion.vhd @@ -24,20 +24,20 @@ use work.AxiLitePkg.all; entity AxiVersion is generic ( - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; BUILD_INFO_G : BuildInfoType; - SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; - DEVICE_ID_G : slv(31 downto 0) := (others => '0'); - CLK_PERIOD_G : real := 8.0E-9; -- units of seconds - XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" - EN_DEVICE_DNA_G : boolean := false; - EN_DS2411_G : boolean := false; - EN_ICAP_G : boolean := false; - USE_SLOWCLK_G : boolean := false; - BUFR_CLK_DIV_G : positive := 8; - AUTO_RELOAD_EN_G : boolean := false; - AUTO_RELOAD_TIME_G : real range 0.0 to 30.0 := 10.0; -- units of seconds - AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); + SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; + DEVICE_ID_G : slv(31 downto 0) := (others => '0'); + CLK_PERIOD_G : real := 8.0E-9; -- units of seconds + XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" + EN_DEVICE_DNA_G : boolean := false; + EN_DS2411_G : boolean := false; + EN_ICAP_G : boolean := false; + USE_SLOWCLK_G : boolean := false; + BUFR_CLK_DIV_G : positive := 8; + AUTO_RELOAD_EN_G : boolean := false; + AUTO_RELOAD_TIME_G : positive := 10; -- units of seconds + AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); port ( -- AXI-Lite Interface axiClk : in sl; @@ -65,7 +65,6 @@ end AxiVersion; architecture rtl of AxiVersion is - constant RELOAD_COUNT_C : integer := integer(AUTO_RELOAD_TIME_G / CLK_PERIOD_G); constant TIMEOUT_1HZ_C : natural := (getTimeRatio(1.0, CLK_PERIOD_G) -1); constant COUNTER_ZERO_C : slv(31 downto 0) := X"00000000"; @@ -76,7 +75,7 @@ architecture rtl of AxiVersion is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : slv(31 downto 0); + counter : natural range 0 to AUTO_RELOAD_TIME_G; counterRst : sl; userReset : sl; fpgaReload : sl; @@ -90,7 +89,7 @@ architecture rtl of AxiVersion is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => (others => '0'), + counter => 0, counterRst => '0', userReset => '0', fpgaReload => '0', @@ -102,8 +101,8 @@ architecture rtl of AxiVersion is signal r : RegType := REG_INIT_C; signal rin : RegType; - signal dnaValue : slv(127 downto 0) := (others => '0'); - signal fdValue : slv(63 downto 0) := (others => '0'); + signal dnaValue : slv(127 downto 0) := (others => '0'); + signal fdValue : slv(63 downto 0) := (others => '0'); attribute rom_style : string; attribute rom_style of BUILD_STRING_ROM_C : constant is "distributed"; @@ -167,19 +166,6 @@ begin -- Latch the current value v := r; - --------------------------------- - -- First Stage Boot Loader (FSBL) - --------------------------------- - -- Check if timer enabled - if fpgaEnReload = '1' then - v.counter := v.counter + 1; - end if; - - -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = RELOAD_COUNT_C) and (fpgaEnReload = '1') and (r.haltReload = '0') then - v.fpgaReload := '1'; - end if; - ------------------------ -- AXI-Lite Transactions ------------------------ @@ -199,20 +185,38 @@ begin axiSlaveRegisterR(axilEp, x"300", 0, fdValue); axiSlaveRegisterR(axilEp, x"400", userValues); axiSlaveRegisterR(axilEp, x"500", 0, DEVICE_ID_G); - + axiSlaveRegisterR(axilEp, x"600", 0, BUILD_INFO_C.gitHash); - + axiSlaveRegisterR(axilEp, x"700", 0, dnaValue); axiSlaveRegisterR(axilEp, x"800", BUILD_STRING_ROM_C); + -- Close the transaction axiSlaveDefault(axilEp, v.axiWriteSlave, v.axiReadSlave, AXI_RESP_DECERR_C); --------------------------------- -- Uptime counter --------------------------------- if r.timer = TIMEOUT_1HZ_C then - v.timer := 0; + -- Reset the counter + v.timer := 0; + + -- Increment the Counter v.upTimeCnt := r.upTimeCnt + 1; + + --------------------------------- + -- First Stage Boot Loader (FSBL) + --------------------------------- + -- Check if timer enabled + if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then + v.counter := r.counter + 1; + end if; + + -- Check for reload condition + if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + v.fpgaReload := '1'; + end if; + else v.timer := r.timer + 1; end if; diff --git a/axi/axi-lite/rtl/AxiVersionLegacy.vhd b/axi/axi-lite/rtl/AxiVersionLegacy.vhd index 8f8245ea9f..07518bd62f 100644 --- a/axi/axi-lite/rtl/AxiVersionLegacy.vhd +++ b/axi/axi-lite/rtl/AxiVersionLegacy.vhd @@ -24,20 +24,20 @@ use work.AxiLitePkg.all; entity AxiVersionLegacy is generic ( - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; BUILD_INFO_G : BuildInfoType; - SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; - DEVICE_ID_G : slv(31 downto 0) := (others => '0'); - CLK_PERIOD_G : real := 8.0E-9; -- units of seconds - XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" - EN_DEVICE_DNA_G : boolean := false; - EN_DS2411_G : boolean := false; - EN_ICAP_G : boolean := false; - USE_SLOWCLK_G : boolean := false; - BUFR_CLK_DIV_G : positive := 8; - AUTO_RELOAD_EN_G : boolean := false; - AUTO_RELOAD_TIME_G : real range 0.0 to 30.0 := 10.0; -- units of seconds - AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); + SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; + DEVICE_ID_G : slv(31 downto 0) := (others => '0'); + CLK_PERIOD_G : real := 8.0E-9; -- units of seconds + XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" + EN_DEVICE_DNA_G : boolean := false; + EN_DS2411_G : boolean := false; + EN_ICAP_G : boolean := false; + USE_SLOWCLK_G : boolean := false; + BUFR_CLK_DIV_G : positive := 8; + AUTO_RELOAD_EN_G : boolean := false; + AUTO_RELOAD_TIME_G : positive := 10; -- units of seconds + AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); port ( -- AXI-Lite Interface axiClk : in sl; @@ -65,7 +65,6 @@ end AxiVersionLegacy; architecture rtl of AxiVersionLegacy is - constant RELOAD_COUNT_C : integer := integer(AUTO_RELOAD_TIME_G / CLK_PERIOD_G); constant TIMEOUT_1HZ_C : natural := (getTimeRatio(1.0, CLK_PERIOD_G) -1); constant COUNTER_ZERO_C : slv(31 downto 0) := X"00000000"; @@ -76,7 +75,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : slv(31 downto 0); + counter : natural range 0 to AUTO_RELOAD_TIME_G; counterRst : sl; userReset : sl; fpgaReload : sl; @@ -90,7 +89,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => (others => '0'), + counter => 0, counterRst => '0', userReset => '1', -- Asserted on powerup fpgaReload => '0', @@ -159,31 +158,17 @@ begin bootAddress => r.fpgaReloadAddr); end generate; - comb : process (axiReadMaster, axiRst, axiWriteMaster, dnaValue, fdValue, fpgaEnReload, r, - userValues) is + comb : process (axiReadMaster, axiRst, axiWriteMaster, dnaValue, fdValue, + fpgaEnReload, r, userValues) is variable v : RegType; variable axilEp : AxiLiteEndpointType; begin -- Latch the current value v := r; - --------------------------------- - -- First Stage Boot Loader (FSBL) - --------------------------------- - -- Check if timer enabled - if fpgaEnReload = '1' then - v.counter := v.counter + 1; - end if; - - -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = RELOAD_COUNT_C) and (fpgaEnReload = '1') and (r.haltReload = '0') then - v.fpgaReload := '1'; - end if; - ------------------------ -- AXI-Lite Transactions ------------------------ - ------------------------ -- Determine the transaction type axiSlaveWaitTxn(axilEp, axiWriteMaster, axiReadMaster, v.axiWriteSlave, v.axiReadSlave); @@ -206,14 +191,32 @@ begin axiSlaveRegisterR(axilEp, X"400", userValues); axiSlaveRegisterR(axilEp, X"800", BUILD_STRING_ROM_C); + -- Close the transaction axiSlaveDefault(axilEp, v.axiWriteSlave, v.axiReadSlave, AXI_RESP_DECERR_C); --------------------------------- -- Uptime counter --------------------------------- if r.timer = TIMEOUT_1HZ_C then - v.timer := 0; + -- Reset the counter + v.timer := 0; + + -- Increment the Counter v.upTimeCnt := r.upTimeCnt + 1; + + --------------------------------- + -- First Stage Boot Loader (FSBL) + --------------------------------- + -- Check if timer enabled + if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then + v.counter := r.counter + 1; + end if; + + -- Check for reload condition + if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + v.fpgaReload := '1'; + end if; + else v.timer := r.timer + 1; end if; From cd619f6a471de8d83a0db060653455659fee0501 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 15:32:07 -0800 Subject: [PATCH 12/37] changing AUTO_RELOAD_TIME_G from real to positive require for CLK of 250 MHz and 10 sec reload time without going out-of-range of integer (2147483647) --- axi/axi-lite/rtl/AxiVersion.vhd | 72 ++++++++++++++------------- axi/axi-lite/rtl/AxiVersionLegacy.vhd | 69 +++++++++++++------------ 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/axi/axi-lite/rtl/AxiVersion.vhd b/axi/axi-lite/rtl/AxiVersion.vhd index 0e960a1ce5..cd4404e29d 100644 --- a/axi/axi-lite/rtl/AxiVersion.vhd +++ b/axi/axi-lite/rtl/AxiVersion.vhd @@ -24,20 +24,20 @@ use work.AxiLitePkg.all; entity AxiVersion is generic ( - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; BUILD_INFO_G : BuildInfoType; - SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; - DEVICE_ID_G : slv(31 downto 0) := (others => '0'); - CLK_PERIOD_G : real := 8.0E-9; -- units of seconds - XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" - EN_DEVICE_DNA_G : boolean := false; - EN_DS2411_G : boolean := false; - EN_ICAP_G : boolean := false; - USE_SLOWCLK_G : boolean := false; - BUFR_CLK_DIV_G : positive := 8; - AUTO_RELOAD_EN_G : boolean := false; - AUTO_RELOAD_TIME_G : real range 0.0 to 30.0 := 10.0; -- units of seconds - AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); + SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; + DEVICE_ID_G : slv(31 downto 0) := (others => '0'); + CLK_PERIOD_G : real := 8.0E-9; -- units of seconds + XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" + EN_DEVICE_DNA_G : boolean := false; + EN_DS2411_G : boolean := false; + EN_ICAP_G : boolean := false; + USE_SLOWCLK_G : boolean := false; + BUFR_CLK_DIV_G : positive := 8; + AUTO_RELOAD_EN_G : boolean := false; + AUTO_RELOAD_TIME_G : positive := 10; -- units of seconds + AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); port ( -- AXI-Lite Interface axiClk : in sl; @@ -65,7 +65,6 @@ end AxiVersion; architecture rtl of AxiVersion is - constant RELOAD_COUNT_C : integer := integer(AUTO_RELOAD_TIME_G / CLK_PERIOD_G); constant TIMEOUT_1HZ_C : natural := (getTimeRatio(1.0, CLK_PERIOD_G) -1); constant COUNTER_ZERO_C : slv(31 downto 0) := X"00000000"; @@ -76,7 +75,7 @@ architecture rtl of AxiVersion is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : slv(31 downto 0); + counter : natural range 0 to AUTO_RELOAD_TIME_G; counterRst : sl; userReset : sl; fpgaReload : sl; @@ -90,7 +89,7 @@ architecture rtl of AxiVersion is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => (others => '0'), + counter => 0, counterRst => '0', userReset => '0', fpgaReload => '0', @@ -102,8 +101,8 @@ architecture rtl of AxiVersion is signal r : RegType := REG_INIT_C; signal rin : RegType; - signal dnaValue : slv(127 downto 0) := (others => '0'); - signal fdValue : slv(63 downto 0) := (others => '0'); + signal dnaValue : slv(127 downto 0) := (others => '0'); + signal fdValue : slv(63 downto 0) := (others => '0'); attribute rom_style : string; attribute rom_style of BUILD_STRING_ROM_C : constant is "distributed"; @@ -167,19 +166,6 @@ begin -- Latch the current value v := r; - --------------------------------- - -- First Stage Boot Loader (FSBL) - --------------------------------- - -- Check if timer enabled - if fpgaEnReload = '1' then - v.counter := v.counter + 1; - end if; - - -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = RELOAD_COUNT_C) and (fpgaEnReload = '1') and (r.haltReload = '0') then - v.fpgaReload := '1'; - end if; - ------------------------ -- AXI-Lite Transactions ------------------------ @@ -199,20 +185,38 @@ begin axiSlaveRegisterR(axilEp, x"300", 0, fdValue); axiSlaveRegisterR(axilEp, x"400", userValues); axiSlaveRegisterR(axilEp, x"500", 0, DEVICE_ID_G); - + axiSlaveRegisterR(axilEp, x"600", 0, BUILD_INFO_C.gitHash); - + axiSlaveRegisterR(axilEp, x"700", 0, dnaValue); axiSlaveRegisterR(axilEp, x"800", BUILD_STRING_ROM_C); + -- Close the transaction axiSlaveDefault(axilEp, v.axiWriteSlave, v.axiReadSlave, AXI_RESP_DECERR_C); --------------------------------- -- Uptime counter --------------------------------- if r.timer = TIMEOUT_1HZ_C then - v.timer := 0; + -- Reset the counter + v.timer := 0; + + -- Increment the Counter v.upTimeCnt := r.upTimeCnt + 1; + + --------------------------------- + -- First Stage Boot Loader (FSBL) + --------------------------------- + -- Check if timer enabled + if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then + v.counter := r.counter + 1; + end if; + + -- Check for reload condition + if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + v.fpgaReload := '1'; + end if; + else v.timer := r.timer + 1; end if; diff --git a/axi/axi-lite/rtl/AxiVersionLegacy.vhd b/axi/axi-lite/rtl/AxiVersionLegacy.vhd index 8f8245ea9f..07518bd62f 100644 --- a/axi/axi-lite/rtl/AxiVersionLegacy.vhd +++ b/axi/axi-lite/rtl/AxiVersionLegacy.vhd @@ -24,20 +24,20 @@ use work.AxiLitePkg.all; entity AxiVersionLegacy is generic ( - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; BUILD_INFO_G : BuildInfoType; - SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; - DEVICE_ID_G : slv(31 downto 0) := (others => '0'); - CLK_PERIOD_G : real := 8.0E-9; -- units of seconds - XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" - EN_DEVICE_DNA_G : boolean := false; - EN_DS2411_G : boolean := false; - EN_ICAP_G : boolean := false; - USE_SLOWCLK_G : boolean := false; - BUFR_CLK_DIV_G : positive := 8; - AUTO_RELOAD_EN_G : boolean := false; - AUTO_RELOAD_TIME_G : real range 0.0 to 30.0 := 10.0; -- units of seconds - AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); + SIM_DNA_VALUE_G : slv := X"000000000000000000000000"; + DEVICE_ID_G : slv(31 downto 0) := (others => '0'); + CLK_PERIOD_G : real := 8.0E-9; -- units of seconds + XIL_DEVICE_G : string := "7SERIES"; -- Either "7SERIES" or "ULTRASCALE" + EN_DEVICE_DNA_G : boolean := false; + EN_DS2411_G : boolean := false; + EN_ICAP_G : boolean := false; + USE_SLOWCLK_G : boolean := false; + BUFR_CLK_DIV_G : positive := 8; + AUTO_RELOAD_EN_G : boolean := false; + AUTO_RELOAD_TIME_G : positive := 10; -- units of seconds + AUTO_RELOAD_ADDR_G : slv(31 downto 0) := (others => '0')); port ( -- AXI-Lite Interface axiClk : in sl; @@ -65,7 +65,6 @@ end AxiVersionLegacy; architecture rtl of AxiVersionLegacy is - constant RELOAD_COUNT_C : integer := integer(AUTO_RELOAD_TIME_G / CLK_PERIOD_G); constant TIMEOUT_1HZ_C : natural := (getTimeRatio(1.0, CLK_PERIOD_G) -1); constant COUNTER_ZERO_C : slv(31 downto 0) := X"00000000"; @@ -76,7 +75,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : slv(31 downto 0); + counter : natural range 0 to AUTO_RELOAD_TIME_G; counterRst : sl; userReset : sl; fpgaReload : sl; @@ -90,7 +89,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => (others => '0'), + counter => 0, counterRst => '0', userReset => '1', -- Asserted on powerup fpgaReload => '0', @@ -159,31 +158,17 @@ begin bootAddress => r.fpgaReloadAddr); end generate; - comb : process (axiReadMaster, axiRst, axiWriteMaster, dnaValue, fdValue, fpgaEnReload, r, - userValues) is + comb : process (axiReadMaster, axiRst, axiWriteMaster, dnaValue, fdValue, + fpgaEnReload, r, userValues) is variable v : RegType; variable axilEp : AxiLiteEndpointType; begin -- Latch the current value v := r; - --------------------------------- - -- First Stage Boot Loader (FSBL) - --------------------------------- - -- Check if timer enabled - if fpgaEnReload = '1' then - v.counter := v.counter + 1; - end if; - - -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = RELOAD_COUNT_C) and (fpgaEnReload = '1') and (r.haltReload = '0') then - v.fpgaReload := '1'; - end if; - ------------------------ -- AXI-Lite Transactions ------------------------ - ------------------------ -- Determine the transaction type axiSlaveWaitTxn(axilEp, axiWriteMaster, axiReadMaster, v.axiWriteSlave, v.axiReadSlave); @@ -206,14 +191,32 @@ begin axiSlaveRegisterR(axilEp, X"400", userValues); axiSlaveRegisterR(axilEp, X"800", BUILD_STRING_ROM_C); + -- Close the transaction axiSlaveDefault(axilEp, v.axiWriteSlave, v.axiReadSlave, AXI_RESP_DECERR_C); --------------------------------- -- Uptime counter --------------------------------- if r.timer = TIMEOUT_1HZ_C then - v.timer := 0; + -- Reset the counter + v.timer := 0; + + -- Increment the Counter v.upTimeCnt := r.upTimeCnt + 1; + + --------------------------------- + -- First Stage Boot Loader (FSBL) + --------------------------------- + -- Check if timer enabled + if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then + v.counter := r.counter + 1; + end if; + + -- Check for reload condition + if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + v.fpgaReload := '1'; + end if; + else v.timer := r.timer + 1; end if; From c6929bb9abfe88ef4954fa11403ffadaa7423dfa Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 19 Feb 2019 15:45:15 -0800 Subject: [PATCH 13/37] adding 256 TDEST support to AxiStreamDeMux & AxiStreamMux --- axi/axi-stream/rtl/AxiStreamDeMux.vhd | 14 +++++++------- axi/axi-stream/rtl/AxiStreamMux.vhd | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamDeMux.vhd b/axi/axi-stream/rtl/AxiStreamDeMux.vhd index 1da9cb399e..eb3d3b16a6 100644 --- a/axi/axi-stream/rtl/AxiStreamDeMux.vhd +++ b/axi/axi-stream/rtl/AxiStreamDeMux.vhd @@ -24,13 +24,13 @@ use work.AxiStreamPkg.all; entity AxiStreamDeMux is generic ( - TPD_G : time := 1 ns; - NUM_MASTERS_G : integer range 1 to 32 := 12; - MODE_G : string := "INDEXED"; -- Or "ROUTED" - TDEST_ROUTES_G : slv8Array := (0 => "--------"); -- Only used in ROUTED mode - PIPE_STAGES_G : integer range 0 to 16 := 0; - TDEST_HIGH_G : integer range 0 to 7 := 7; - TDEST_LOW_G : integer range 0 to 7 := 0); + TPD_G : time := 1 ns; + NUM_MASTERS_G : integer range 1 to 256 := 12; + MODE_G : string := "INDEXED"; -- Or "ROUTED" + TDEST_ROUTES_G : slv8Array := (0 => "--------"); -- Only used in ROUTED mode + PIPE_STAGES_G : integer range 0 to 16 := 0; + TDEST_HIGH_G : integer range 0 to 7 := 7; + TDEST_LOW_G : integer range 0 to 7 := 0); port ( -- Clock and reset axisClk : in sl; diff --git a/axi/axi-stream/rtl/AxiStreamMux.vhd b/axi/axi-stream/rtl/AxiStreamMux.vhd index 6f69cf125c..429e7aedb8 100644 --- a/axi/axi-stream/rtl/AxiStreamMux.vhd +++ b/axi/axi-stream/rtl/AxiStreamMux.vhd @@ -26,29 +26,29 @@ use work.AxiStreamPkg.all; entity AxiStreamMux is generic ( - TPD_G : time := 1 ns; - PIPE_STAGES_G : integer range 0 to 16 := 0; - NUM_SLAVES_G : integer range 1 to 32 := 4; + TPD_G : time := 1 ns; + PIPE_STAGES_G : integer range 0 to 16 := 0; + NUM_SLAVES_G : integer range 1 to 256 := 4; -- In INDEXED mode, the output TDEST is set based on the selected slave index -- In ROUTED mode, TDEST is set accoring to the TDEST_ROUTES_G table - MODE_G : string := "INDEXED"; + MODE_G : string := "INDEXED"; -- In ROUTED mode, an array mapping how TDEST should be assigned for each slave port -- Each TDEST bit can be set to '0', '1' or '-' for passthrough from slave TDEST. - TDEST_ROUTES_G : Slv8Array := (0 => "--------"); + TDEST_ROUTES_G : Slv8Array := (0 => "--------"); -- In INDEXED mode, assign slave index to TDEST at this bit offset - TDEST_LOW_G : integer range 0 to 7 := 0; + TDEST_LOW_G : integer range 0 to 7 := 0; -- Set to true if interleaving dests - ILEAVE_EN_G : boolean := false; + ILEAVE_EN_G : boolean := false; -- Rearbitrate when tValid drops on selected channel, ignored when ILEAVE_EN_G=false - ILEAVE_ON_NOTVALID_G : boolean := false; + ILEAVE_ON_NOTVALID_G : boolean := false; -- Max number of transactions between arbitrations, 0 = unlimited, ignored when ILEAVE_EN_G=false - ILEAVE_REARB_G : natural := 0; + ILEAVE_REARB_G : natural := 0; -- One cycle gap in stream between during rearbitration. -- Set true for better timing, false for higher throughput. - REARB_DELAY_G : boolean := true; + REARB_DELAY_G : boolean := true; -- Block selected slave txns arriving on same cycle as rearbitrate or disableSel from going through, -- creating 1 cycle gap. This might be needed logically but decreases throughput. - FORCED_REARB_HOLD_G : boolean := false); + FORCED_REARB_HOLD_G : boolean := false); port ( -- Clock and reset From b6e790801ebf3292e3f5828e4d85e5911f6add26 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 19 Feb 2019 21:10:33 -0800 Subject: [PATCH 14/37] Fix AxiVersion Variables --- python/surf/axi/_AxiVersion.py | 38 +++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index 46015f146b..67adc709ec 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -218,38 +218,42 @@ def UserRst(): )) - def parseBuildStamp(var, value, disp): - p = parse.parse("{ImageName}: {BuildEnv}, {BuildServer}, Built {BuildDate} by {Builder}", value.strip()) - if p is not None: - for k,v in p.named.items(): - self.node(k).set(v) + def parseBuildStamp(var,read): + p = parse.parse("{ImageName}: {BuildEnv}, {BuildServer}, Built {BuildDate} by {Builder}", var.dependencies[0].get(read)) + if p is None: + return '' + else: + return p[var.name] - self.add(pr.LocalVariable( + self.add(pr.LinkVariable( name = 'ImageName', mode = 'RO', - value = '')) + linkedGet = parseBuildStamp, + variable = self.BuildStamp)) - self.add(pr.LocalVariable( + self.add(pr.LinkVariable( name = 'BuildEnv', mode = 'RO', - value = '')) + linkedGet = parseBuildStamp, + variable = self.BuildStamp)) - self.add(pr.LocalVariable( + self.add(pr.LinkVariable( name = 'BuildServer', mode = 'RO', - value = '')) + linkedGet = parseBuildStamp, + variable = self.BuildStamp)) - self.add(pr.LocalVariable( + self.add(pr.LinkVariable( name = 'BuildDate', mode = 'RO', - value = '')) + linkedGet = parseBuildStamp, + variable = self.BuildStamp)) - self.add(pr.LocalVariable( + self.add(pr.LinkVariable( name = 'Builder', mode = 'RO', - value = '')) - - self.BuildStamp.addListener(parseBuildStamp) + linkedGet = parseBuildStamp, + variable = self.BuildStamp)) def hardReset(self): From 0709aefc4388b5105780eb2d2b74bd01c0609813 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 19 Feb 2019 21:24:01 -0800 Subject: [PATCH 15/37] Cleanup --- python/surf/axi/_AxiVersion.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index 67adc709ec..e598c3f36a 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -85,7 +85,7 @@ def __init__( description = 'Time since power up or last firmware reload', mode = 'RO', dependencies = [self.UpTimeCnt], - linkedGet = lambda: str(datetime.timedelta(seconds=self.UpTimeCnt.value())), + linkedGet = lambda read: str(datetime.timedelta(seconds=self.UpTimeCnt.get(read))), units = 'HH:MM:SS', )) @@ -193,7 +193,7 @@ def UserRst(): mode = 'RO', dependencies = [self.GitHash], disp = '{:07x}', - linkedGet = lambda: self.GitHash.value() >> 132, + linkedGet = lambda read: self.GitHash.get(read) >> 132, )) self.add(pr.RemoteVariable( @@ -267,8 +267,6 @@ def countReset(self): def printStatus(self): try: - self.UpTimeCnt.get() - self.BuildStamp.get() gitHash = self.GitHash.get() print("FwVersion = {}".format(hex(self.FpgaVersion.get()))) print("UpTime = {}".format(self.UpTime.get())) @@ -277,11 +275,11 @@ def printStatus(self): else: print("GitHash = dirty (uncommitted code)") print("XilinxDnaId = {}".format(hex(self.DeviceDna.get()))) - print("FwTarget = {}".format(self.ImageName.get())) - print("BuildEnv = {}".format(self.BuildEnv.get())) - print("BuildServer = {}".format(self.BuildServer.get())) - print("BuildDate = {}".format(self.BuildDate.get())) - print("Builder = {}".format(self.Builder.get())) + print("FwTarget = {}".format(self.ImageName.get())) # Read buildstamp here + print("BuildEnv = {}".format(self.BuildEnv.value())) + print("BuildServer = {}".format(self.BuildServer.value())) + print("BuildDate = {}".format(self.BuildDate.value())) + print("Builder = {}".format(self.Builder.value())) except Exception as e: print("Failed to get AxiVersion status") From 63061160dd6942503d13e75c0fa230fd2804fc25 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 19 Feb 2019 21:33:46 -0800 Subject: [PATCH 16/37] Pass varable instead of dependencies --- python/surf/axi/_AxiVersion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index e598c3f36a..ef981842cb 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -84,7 +84,7 @@ def __init__( name = 'UpTime', description = 'Time since power up or last firmware reload', mode = 'RO', - dependencies = [self.UpTimeCnt], + variable = self.UpTimeCnt, linkedGet = lambda read: str(datetime.timedelta(seconds=self.UpTimeCnt.get(read))), units = 'HH:MM:SS', )) @@ -191,7 +191,7 @@ def UserRst(): self.add(pr.LinkVariable( name = 'GitHashShort', mode = 'RO', - dependencies = [self.GitHash], + variable = self.GitHash, disp = '{:07x}', linkedGet = lambda read: self.GitHash.get(read) >> 132, )) From f9aef1f788f5d6db87680847b9cd085a46af6466 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 19 Feb 2019 21:38:11 -0800 Subject: [PATCH 17/37] Fix display --- python/surf/axi/_AxiVersion.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index ef981842cb..426382509d 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -84,6 +84,7 @@ def __init__( name = 'UpTime', description = 'Time since power up or last firmware reload', mode = 'RO', + disp = '{}', variable = self.UpTimeCnt, linkedGet = lambda read: str(datetime.timedelta(seconds=self.UpTimeCnt.get(read))), units = 'HH:MM:SS', From 3206613bea339f077cd81544758dacb2c25a131a Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 19 Feb 2019 22:42:37 -0800 Subject: [PATCH 18/37] Fix receive timeout --- axi/simlink/src/RogueSideBand.c | 4 ---- axi/simlink/src/RogueTcpMemory.c | 7 +------ axi/simlink/src/RogueTcpStream.c | 7 +------ 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index 6c5bce53b6..21d498bd2f 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -26,7 +26,6 @@ // Start/resetart zeromq server void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData) { char buffer[100]; - uint32_t to; if ( data->zmqPull != NULL ) zmq_close(data->zmqPull); if ( data->zmqCtx != NULL ) zmq_term(data->zmqCtx); @@ -37,9 +36,6 @@ void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData) { data->zmqCtx = zmq_ctx_new(); data->zmqPull = zmq_socket(data->zmqCtx,ZMQ_REP); - to = 10; - zmq_setsockopt (data->zmqPull, ZMQ_RCVTIMEO, &to, sizeof(to)); - vhpi_printf("RogueSideBand: Listening on port %i\n",data->port); sprintf(buffer,"tcp://*:%i",data->port); diff --git a/axi/simlink/src/RogueTcpMemory.c b/axi/simlink/src/RogueTcpMemory.c index 283799d8f1..4f242715df 100755 --- a/axi/simlink/src/RogueTcpMemory.c +++ b/axi/simlink/src/RogueTcpMemory.c @@ -26,7 +26,6 @@ // Start/resetart zeromq server void RogueTcpMemoryRestart(RogueTcpMemoryData *data, portDataT *portData) { char buffer[100]; - uint32_t to; if ( data->zmqPush != NULL ) zmq_close(data->zmqPull); if ( data->zmqPull != NULL ) zmq_close(data->zmqPush); @@ -40,10 +39,6 @@ void RogueTcpMemoryRestart(RogueTcpMemoryData *data, portDataT *portData) { data->zmqPull = zmq_socket(data->zmqCtx,ZMQ_PULL); data->zmqPush = zmq_socket(data->zmqCtx,ZMQ_PUSH); - to = 10; - zmq_setsockopt (data->zmqPull, ZMQ_RCVTIMEO, &to, sizeof(to)); - zmq_setsockopt (data->zmqPush, ZMQ_RCVTIMEO, &to, sizeof(to)); - vhpi_printf("RogueTcpMemory: Listening on ports %i & %i\n",data->port,data->port+1); sprintf(buffer,"tcp://*:%i",data->port); @@ -116,7 +111,7 @@ int RogueTcpMemoryRecv ( RogueTcpMemoryData *data, portDataT *portData ) { do { // Get the message - if ( zmq_recvmsg(data->zmqPull,&(msg[x]),0) > 0 ) { + if ( zmq_recvmsg(data->zmqPull,&(msg[x]),ZMQ_DONTWAIT) > 0 ) { if ( x != 4 ) x++; msgCnt++; diff --git a/axi/simlink/src/RogueTcpStream.c b/axi/simlink/src/RogueTcpStream.c index ddd0a95e4b..8ce57aa80c 100755 --- a/axi/simlink/src/RogueTcpStream.c +++ b/axi/simlink/src/RogueTcpStream.c @@ -26,7 +26,6 @@ // Start/resetart zeromq server void RogueTcpStreamRestart(RogueTcpStreamData *data, portDataT *portData) { char buffer[100]; - uint32_t to; if ( data->zmqPush != NULL ) zmq_close(data->zmqPush ); if ( data->zmqPull != NULL ) zmq_close(data->zmqPush ); @@ -40,10 +39,6 @@ void RogueTcpStreamRestart(RogueTcpStreamData *data, portDataT *portData) { data->zmqPull = zmq_socket(data->zmqCtx,ZMQ_PULL); data->zmqPush = zmq_socket(data->zmqCtx,ZMQ_PUSH); - to = 10; - zmq_setsockopt (data->zmqPull, ZMQ_RCVTIMEO, &to, sizeof(to)); - zmq_setsockopt (data->zmqPush, ZMQ_RCVTIMEO, &to, sizeof(to)); - vhpi_printf("RogueTcpStream: Listening on ports %i & %i\n",data->port,data->port+1); sprintf(buffer,"tcp://*:%i",data->port); @@ -128,7 +123,7 @@ int RogueTcpStreamRecv ( RogueTcpStreamData *data, portDataT *portData ) { do { // Get the message - if ( zmq_recvmsg(data->zmqPull,&(msg[x]),0) > 0 ) { + if ( zmq_recvmsg(data->zmqPull,&(msg[x]),ZMQ_DONTWAIT) > 0 ) { if ( x != 3 ) x++; msgCnt++; From 93986e420054f52d4c500bb1de2cc85557fcc243 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 20 Feb 2019 08:42:41 -0800 Subject: [PATCH 19/37] rename to and removed r.counterRst --- axi/axi-lite/rtl/AxiVersion.vhd | 12 +++++------- axi/axi-lite/rtl/AxiVersionLegacy.vhd | 14 ++++++-------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/axi/axi-lite/rtl/AxiVersion.vhd b/axi/axi-lite/rtl/AxiVersion.vhd index cd4404e29d..628bc20d81 100644 --- a/axi/axi-lite/rtl/AxiVersion.vhd +++ b/axi/axi-lite/rtl/AxiVersion.vhd @@ -75,8 +75,7 @@ architecture rtl of AxiVersion is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : natural range 0 to AUTO_RELOAD_TIME_G; - counterRst : sl; + reloadTimer : natural range 0 to AUTO_RELOAD_TIME_G; userReset : sl; fpgaReload : sl; haltReload : sl; @@ -89,8 +88,7 @@ architecture rtl of AxiVersion is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => 0, - counterRst => '0', + reloadTimer => 0, userReset => '0', fpgaReload => '0', haltReload => '0', @@ -208,12 +206,12 @@ begin -- First Stage Boot Loader (FSBL) --------------------------------- -- Check if timer enabled - if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then - v.counter := r.counter + 1; + if (fpgaEnReload = '1') and (r.reloadTimer /= AUTO_RELOAD_TIME_G) then + v.reloadTimer := r.reloadTimer + 1; end if; -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + if AUTO_RELOAD_EN_G and (r.reloadTimer = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then v.fpgaReload := '1'; end if; diff --git a/axi/axi-lite/rtl/AxiVersionLegacy.vhd b/axi/axi-lite/rtl/AxiVersionLegacy.vhd index 07518bd62f..3c367ec11c 100644 --- a/axi/axi-lite/rtl/AxiVersionLegacy.vhd +++ b/axi/axi-lite/rtl/AxiVersionLegacy.vhd @@ -75,8 +75,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt : slv(31 downto 0); timer : natural range 0 to TIMEOUT_1HZ_C; scratchPad : slv(31 downto 0); - counter : natural range 0 to AUTO_RELOAD_TIME_G; - counterRst : sl; + reloadTimer : natural range 0 to AUTO_RELOAD_TIME_G; userReset : sl; fpgaReload : sl; haltReload : sl; @@ -89,8 +88,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - counter => 0, - counterRst => '0', + reloadTimer => 0, userReset => '1', -- Asserted on powerup fpgaReload => '0', haltReload => '0', @@ -181,7 +179,7 @@ begin axiSlaveRegister(axilEp, X"01C", 0, v.fpgaReload); axiSlaveRegister(axilEp, X"020", 0, v.fpgaReloadAddr); - axiSlaveRegister(axilEp, X"024", 0, v.counter, COUNTER_ZERO_C); + axiSlaveRegister(axilEp, X"024", 0, v.reloadTimer, COUNTER_ZERO_C); axiSlaveRegister(axilEp, X"028", 0, v.haltReload); axiSlaveRegisterR(axilEp, X"02C", 0, r.upTimeCnt); axiSlaveRegisterR(axilEp, X"030", 0, DEVICE_ID_G); @@ -208,12 +206,12 @@ begin -- First Stage Boot Loader (FSBL) --------------------------------- -- Check if timer enabled - if (fpgaEnReload = '1') and (r.counter /= AUTO_RELOAD_TIME_G) then - v.counter := r.counter + 1; + if (fpgaEnReload = '1') and (r.reloadTimer /= AUTO_RELOAD_TIME_G) then + v.reloadTimer := r.reloadTimer + 1; end if; -- Check for reload condition - if AUTO_RELOAD_EN_G and (r.counter = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then + if AUTO_RELOAD_EN_G and (r.reloadTimer = AUTO_RELOAD_TIME_G) and (fpgaEnReload = '1') and (r.haltReload = '0') then v.fpgaReload := '1'; end if; From ce3684f82ebb29ddaf11b190fcc97dd141b197ba Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 20 Feb 2019 10:16:18 -0800 Subject: [PATCH 20/37] updating AXI-Lite bus from 'axi' to 'axil' naming convention --- axi/simlink/sim/RogueTcpMemoryWrap.vhd | 54 +++++++++++++------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/axi/simlink/sim/RogueTcpMemoryWrap.vhd b/axi/simlink/sim/RogueTcpMemoryWrap.vhd index 69cab2f8ae..f9e6ea71b3 100755 --- a/axi/simlink/sim/RogueTcpMemoryWrap.vhd +++ b/axi/simlink/sim/RogueTcpMemoryWrap.vhd @@ -27,12 +27,12 @@ entity RogueTcpMemoryWrap is PORT_NUM_G : natural range 0 to 65535 := 1 ); port ( - axiClk : in sl; - axiRst : in sl; - axiReadMaster : out AxiLiteReadMasterType; - axiReadSlave : in AxiLiteReadSlaveType; - axiWriteMaster : out AxiLiteWriteMasterType; - axiWriteSlave : in AxiLiteWriteSlaveType + axilClk : in sl; + axilRst : in sl; + axilReadMaster : out AxiLiteReadMasterType; + axilReadSlave : in AxiLiteReadSlaveType; + axilWriteMaster : out AxiLiteWriteMasterType; + axilWriteSlave : in AxiLiteWriteSlaveType ); end RogueTcpMemoryWrap; @@ -44,28 +44,28 @@ begin -- Sim Core U_RogueTcpMemory : entity work.RogueTcpMemory port map ( - clock => axiClk, - reset => axiRst, + clock => axilClk, + reset => axilRst, portNum => toSlv(PORT_NUM_G,16), - araddr => axiReadMaster.araddr, - arprot => axiReadMaster.arprot, - arvalid => axiReadMaster.arvalid, - rready => axiReadMaster.rready, - arready => axiReadSlave.arready, - rdata => axiReadSlave.rdata, - rresp => axiReadSlave.rresp, - rvalid => axiReadSlave.rvalid, - awaddr => axiWriteMaster.awaddr, - awprot => axiWriteMaster.awprot, - awvalid => axiWriteMaster.awvalid, - wdata => axiWriteMaster.wdata, - wstrb => axiWriteMaster.wstrb, - wvalid => axiWriteMaster.wvalid, - bready => axiWriteMaster.bready, - awready => axiWriteSlave.awready, - wready => axiWriteSlave.wready, - bresp => axiWriteSlave.bresp, - bvalid => axiWriteSlave.bvalid); + araddr => axilReadMaster.araddr, + arprot => axilReadMaster.arprot, + arvalid => axilReadMaster.arvalid, + rready => axilReadMaster.rready, + arready => axilReadSlave.arready, + rdata => axilReadSlave.rdata, + rresp => axilReadSlave.rresp, + rvalid => axilReadSlave.rvalid, + awaddr => axilWriteMaster.awaddr, + awprot => axilWriteMaster.awprot, + awvalid => axilWriteMaster.awvalid, + wdata => axilWriteMaster.wdata, + wstrb => axilWriteMaster.wstrb, + wvalid => axilWriteMaster.wvalid, + bready => axilWriteMaster.bready, + awready => axilWriteSlave.awready, + wready => axilWriteSlave.wready, + bresp => axilWriteSlave.bresp, + bvalid => axilWriteSlave.bvalid); end RogueTcpMemoryWrap; From 56240b217fae3d66c19d3d653d02e8a9ef89e63c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 20 Feb 2019 10:17:08 -0800 Subject: [PATCH 21/37] In RogueTcpStreamWrap: replacing the FIFOs to resizers and making single clock domain --- axi/simlink/sim/RogueTcpStreamWrap.vhd | 114 +++++++++----------- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 10 +- 2 files changed, 55 insertions(+), 69 deletions(-) mode change 100755 => 100644 axi/simlink/sim/RogueTcpStreamWrap.vhd diff --git a/axi/simlink/sim/RogueTcpStreamWrap.vhd b/axi/simlink/sim/RogueTcpStreamWrap.vhd old mode 100755 new mode 100644 index 9d73cbb0cb..a2efb2d51c --- a/axi/simlink/sim/RogueTcpStreamWrap.vhd +++ b/axi/simlink/sim/RogueTcpStreamWrap.vhd @@ -22,32 +22,21 @@ use work.AxiStreamPkg.all; entity RogueTcpStreamWrap is generic ( - TPD_G : time := 1 ns; - PORT_NUM_G : natural range 0 to 65535 := 1; - SSI_EN_G : boolean := true; - CHAN_COUNT_G : positive range 1 to 256 := 1; - COMMON_MASTER_CLK_G : boolean := false; - COMMON_SLAVE_CLK_G : boolean := false; - AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C - ); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 0 to 65535 := 1; + SSI_EN_G : boolean := true; + CHAN_COUNT_G : positive range 1 to 256 := 1; + AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( - - -- Main Clock and reset used internally - clk : in sl; - rst : in sl; - - -- Slave - sAxisClk : in sl; -- Set COMMON_SLAVE_CLK_G if same as clk input - sAxisRst : in sl; + -- Clock and Reset + axisClk : in sl; + axisRst : in sl; + -- Slave Port sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; - - -- Master - mAxisClk : in sl; -- Set COMMON_MASTER_CLK_G if same as clk input - mAxisRst : in sl; + -- Master Port mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType - ); + mAxisSlave : in AxiStreamSlaveType); end RogueTcpStreamWrap; -- Define architecture @@ -78,41 +67,43 @@ begin assert (PORT_NUM_G + 2*(CHAN_COUNT_G-1) <= 65535) report "PORT_NUM_G + 2*(CHAN_COUNT_G-1) must less than or equal to 65535" severity failure; - ------------------------------------ - -- Inbound Demux - ------------------------------------ - U_DeMux: entity work.AxiStreamDeMux + ---------------- + -- Inbound DEMUX + ---------------- + U_DeMux : entity work.AxiStreamDeMux generic map ( - TPD_G => 1 ns, - NUM_MASTERS_G => CHAN_COUNT_G - ) port map ( + TPD_G => 1 ns, + NUM_MASTERS_G => CHAN_COUNT_G) + port map ( -- Clock and reset - axisClk => sAxisClk, - axisRst => sAxisRst, + axisClk => axisClk, + axisRst => axisRst, sAxisMaster => sAxisMaster, sAxisSlave => sAxisSlave, mAxisMasters => dmMasters, mAxisSlaves => dmSlaves); -- Channels - U_ChanGen: for i in 0 to CHAN_COUNT_G-1 generate + U_ChanGen : for i in 0 to CHAN_COUNT_G-1 generate - ------------------------------------ - -- Inbound FIFOs - ------------------------------------ - U_IbFifo : entity work.AxiStreamFifoV2 + ------------------ + -- Inbound Resizer + ------------------ + U_Ib_Resize : entity work.AxiStreamResize generic map ( + -- General Configurations TPD_G => TPD_G, - GEN_SYNC_FIFO_G => COMMON_SLAVE_CLK_G, + -- AXI Stream Port Configurations SLAVE_AXI_CONFIG_G => AXIS_CONFIG_G, MASTER_AXI_CONFIG_G => INT_CONFIG_C) port map ( - sAxisClk => sAxisClk, - sAxisRst => sAxisRst, + -- Clock and reset + axisClk => axisClk, + axisRst => axisRst, + -- Slave Port sAxisMaster => dmMasters(i), sAxisSlave => dmSlaves(i), - mAxisClk => clk, - mAxisRst => rst, + -- Master Port mAxisMaster => ibMasters(i), mAxisSlave => ibSlaves(i)); @@ -121,8 +112,8 @@ begin ------------------------------------ U_RogueTcpStream : entity work.RogueTcpStream port map( - clock => clk, - reset => rst, + clock => axisClk, + reset => axisRst, portNum => toSlv(PORT_NUM_G + i*2, 16), ssi => toSl(SSI_EN_G), obValid => obMasters(i).tValid, @@ -150,41 +141,42 @@ begin obMasters(i).tData(AXI_STREAM_MAX_TDATA_WIDTH_C-1 downto 64) <= (others => '0'); obMasters(i).tUser(AXI_STREAM_MAX_TDATA_WIDTH_C-1 downto 64) <= (others => '0'); - ------------------------------------ - -- Outbound FIFOs - ------------------------------------ - U_ObFifo : entity work.AxiStreamFifoV2 + ------------------- + -- Outbound Resizer + ------------------- + U_Ob_Resize : entity work.AxiStreamResize generic map ( + -- General Configurations TPD_G => TPD_G, - GEN_SYNC_FIFO_G => COMMON_MASTER_CLK_G, + -- AXI Stream Port Configurations SLAVE_AXI_CONFIG_G => INT_CONFIG_C, MASTER_AXI_CONFIG_G => AXIS_CONFIG_G) port map ( - sAxisClk => clk, - sAxisRst => rst, + -- Clock and reset + axisClk => axisClk, + axisRst => axisRst, + -- Slave Port sAxisMaster => obMasters(i), sAxisSlave => obSlaves(i), - mAxisClk => mAxisClk, - mAxisRst => mAxisRst, + -- Master Port mAxisMaster => mxMasters(i), mAxisSlave => mxSlaves(i)); end generate; - ------------------------------------ - -- Outbound Mux - ------------------------------------ - U_Mux: entity work.AxiStreamMux + --------------- + -- Outbound MUX + --------------- + U_Mux : entity work.AxiStreamMux generic map ( TPD_G => 1 ns, - NUM_SLAVES_G => CHAN_COUNT_G - ) port map ( - axisClk => mAxisClk, - axisRst => mAxisRst, + NUM_SLAVES_G => CHAN_COUNT_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, sAxisMasters => mxMasters, sAxisSlaves => mxSlaves, mAxisMaster => mAxisMaster, mAxisSlave => mAxisSlave); end RogueTcpStreamWrap; - diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index 0fcb0cfd18..91886ce56c 100644 --- a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd +++ b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd @@ -97,18 +97,12 @@ begin PORT_NUM_G => (PORT_NUM_G + i*2), SSI_EN_G => true, CHAN_COUNT_G => 1, - COMMON_MASTER_CLK_G => true, - COMMON_SLAVE_CLK_G => true, AXIS_CONFIG_G => PGP3_AXIS_CONFIG_C) port map ( - clk => clk, -- [in] - rst => rst, -- [in] - sAxisClk => clk, -- [in] - sAxisRst => rst, -- [in] + axisClk => clk, -- [in] + axisRst => rst, -- [in] sAxisMaster => pgpTxMasters(i), -- [in] sAxisSlave => pgpTxSlaves(i), -- [out] - mAxisClk => clk, -- [in] - mAxisRst => rst, -- [in] mAxisMaster => pgpRxMasters(i), -- [out] mAxisSlave => pgpRxSlaves(i)); -- [in] end generate GEN_VEC; From 84f2fcb3eb5ad5a4a0ccff228d07d6be79c8098f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 22 Feb 2019 09:30:17 -0800 Subject: [PATCH 22/37] adding StdMatch() fucntion to StdRtlPkg.vhd --- base/general/rtl/StdRtlPkg.vhd | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/base/general/rtl/StdRtlPkg.vhd b/base/general/rtl/StdRtlPkg.vhd index 897b58642c..194c2ad0f5 100644 --- a/base/general/rtl/StdRtlPkg.vhd +++ b/base/general/rtl/StdRtlPkg.vhd @@ -146,6 +146,13 @@ package StdRtlPkg is function resize (vec : slv; newSize : integer; pad : sl := '0') return slv; function resize (str : string; newSize : integer; pad : character := nul) return string; + -- Match Functions + function StdMatch (L, R: std_ulogic) return boolean; + function StdMatch (L, R: unsigned) return boolean; + function StdMatch (L, R: signed) return boolean; + function StdMatch (L, R: slv) return boolean; + function StdMatch (L, R: std_ulogic_vector) return boolean; + -- Some synthesis tools wont accept unit types -- pragma translate_off type frequency is range 0 to 2147483647 @@ -1364,6 +1371,32 @@ package body StdRtlPkg is return ret; end function resize; + -- Match Functions + function StdMatch (L, R: std_ulogic) return boolean is + begin + return std_match(L,R); + end function StdMatch; + + function StdMatch (L, R: unsigned) return boolean is + begin + return std_match(L,R); + end function StdMatch; + + function StdMatch (L, R: signed) return boolean is + begin + return std_match(L,R); + end function StdMatch; + + function StdMatch (L, R: slv) return boolean is + begin + return std_match(L,R); + end function StdMatch; + + function StdMatch (L, R: std_ulogic_vector) return boolean is + begin + return std_match(L,R); + end function StdMatch; + function toBuildInfo (din : slv) return BuildInfoRetType is variable ret : BuildInfoRetType; variable i : natural; From d479a5766018bf7c9dfe2adfd2c79ecc8ca42859 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Feb 2019 09:29:53 -0800 Subject: [PATCH 23/37] updating AxiLiteCrossbar.vhd to use StdRtlPkg StdMatch instead --- axi/axi-lite/rtl/AxiLiteCrossbar.vhd | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd index a7d1ad17c0..c7c474461d 100644 --- a/axi/axi-lite/rtl/AxiLiteCrossbar.vhd +++ b/axi/axi-lite/rtl/AxiLiteCrossbar.vhd @@ -15,8 +15,8 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; use work.StdRtlPkg.all; use work.AxiLitePkg.all; use work.ArbiterPkg.all; @@ -172,14 +172,14 @@ begin for m in MASTERS_CONFIG_G'range loop -- Check for address match if ( - std_match( -- Use std_match to allow dontcares ('-') + StdMatch( -- Use std_match to allow dontcares ('-') sAxiWriteMasters(s).awaddr(31 downto MASTERS_CONFIG_G(m).addrBits), MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits)) and ( MASTERS_CONFIG_G(m).connectivity(s) = '1')) then v.slave(s).wrReqs(m) := '1'; - v.slave(s).wrReqNum := slv(to_unsigned(m, REQ_NUM_SIZE_C)); + v.slave(s).wrReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); -- print("AxiLiteCrossbar: Slave " & str(s) & " reqd Master " & str(m) & " Write addr " & hstr(sAxiWriteMasters(s).awaddr)); end if; end loop; @@ -205,7 +205,7 @@ begin -- Transaction is acked when S_ACK_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (unsigned(r.slave(s).wrReqNum) = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then + if (r.slave(s).wrReqNum = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then v.sAxiWriteSlaves(s).awready := '1'; v.sAxiWriteSlaves(s).wready := '1'; v.slave(s).wrState := S_TXN_S; @@ -215,7 +215,7 @@ begin -- Transaction in progress when S_TXN_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (unsigned(r.slave(s).wrReqNum) = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then + if (r.slave(s).wrReqNum = m and r.slave(s).wrReqs(m) = '1' and r.master(m).wrAcks(s) = '1') then -- Forward write response v.sAxiWriteSlaves(s).bresp := mAxiWriteSlaves(m).bresp; @@ -240,14 +240,14 @@ begin for m in MASTERS_CONFIG_G'range loop -- Check for address match if ( - std_match( -- Use std_match to allow dontcares ('-') + StdMatch( -- Use std_match to allow dontcares ('-') sAxiReadMasters(s).araddr(31 downto MASTERS_CONFIG_G(m).addrBits), MASTERS_CONFIG_G(m).baseAddr(31 downto MASTERS_CONFIG_G(m).addrBits)) and ( MASTERS_CONFIG_G(m).connectivity(s) = '1')) then v.slave(s).rdReqs(m) := '1'; - v.slave(s).rdReqNum := slv(to_unsigned(m, REQ_NUM_SIZE_C)); + v.slave(s).rdReqNum := conv_std_logic_vector(m, REQ_NUM_SIZE_C); end if; end loop; @@ -272,7 +272,7 @@ begin -- Transaction is acked when S_ACK_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (unsigned(r.slave(s).rdReqNum) = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then + if (r.slave(s).rdReqNum = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then v.sAxiReadSlaves(s).arready := '1'; v.slave(s).rdState := S_TXN_S; end if; @@ -281,7 +281,7 @@ begin -- Transaction in progress when S_TXN_S => for m in NUM_MASTER_SLOTS_G-1 downto 0 loop - if (unsigned(r.slave(s).rdReqNum) = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then + if (r.slave(s).rdReqNum = m and r.slave(s).rdReqs(m) = '1' and r.master(m).rdAcks(s) = '1') then -- Forward read response v.sAxiReadSlaves(s).rresp := mAxiReadSlaves(m).rresp; @@ -328,7 +328,7 @@ begin -- busses to this master's outputs. if (r.master(m).wrValid = '1') then v.master(m).wrAcks := r.master(m).wrAcks; - v.mAxiWriteMasters(m) := sAxiWriteMasters(to_integer(unsigned(r.master(m).wrAckNum))); + v.mAxiWriteMasters(m) := sAxiWriteMasters(conv_integer(r.master(m).wrAckNum)); v.master(m).wrState := M_WAIT_READYS_S; end if; @@ -351,7 +351,7 @@ begin when M_WAIT_REQ_FALL_S => -- When slave side deasserts request, clear ack and valid and start waiting for next -- request - if (mWrReqs(to_integer(unsigned(r.master(m).wrAckNum))) = '0') then + if (mWrReqs(conv_integer(r.master(m).wrAckNum)) = '0') then v.master(m).wrState := M_WAIT_REQ_S; v.master(m).wrAcks := (others => '0'); v.master(m).wrValid := '0'; @@ -384,7 +384,7 @@ begin -- busses to this master's outputs. if (r.master(m).rdValid = '1') then v.master(m).rdAcks := r.master(m).rdAcks; - v.mAxiReadMasters(m) := sAxiReadMasters(to_integer(unsigned(r.master(m).rdAckNum))); + v.mAxiReadMasters(m) := sAxiReadMasters(conv_integer(r.master(m).rdAckNum)); v.master(m).rdState := M_WAIT_READYS_S; end if; @@ -404,7 +404,7 @@ begin when M_WAIT_REQ_FALL_S => -- When slave side deasserts request, clear ack and valid and start waiting for next -- request - if (mRdReqs(to_integer(unsigned(r.master(m).rdAckNum))) = '0') then + if (mRdReqs(conv_integer(r.master(m).rdAckNum)) = '0') then v.master(m).rdState := M_WAIT_REQ_S; v.master(m).rdAcks := (others => '0'); v.master(m).rdValid := '0'; From cc9c775e40c258e351d7c882ebbab903721fa22b Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Feb 2019 14:47:52 -0800 Subject: [PATCH 24/37] Remove std_ulogic_vector variant of StdMatch(), as it seems to cause a compile error --- base/general/rtl/StdRtlPkg.vhd | 5 ----- 1 file changed, 5 deletions(-) diff --git a/base/general/rtl/StdRtlPkg.vhd b/base/general/rtl/StdRtlPkg.vhd index 194c2ad0f5..11489dd4fa 100644 --- a/base/general/rtl/StdRtlPkg.vhd +++ b/base/general/rtl/StdRtlPkg.vhd @@ -151,7 +151,6 @@ package StdRtlPkg is function StdMatch (L, R: unsigned) return boolean; function StdMatch (L, R: signed) return boolean; function StdMatch (L, R: slv) return boolean; - function StdMatch (L, R: std_ulogic_vector) return boolean; -- Some synthesis tools wont accept unit types -- pragma translate_off @@ -1392,10 +1391,6 @@ package body StdRtlPkg is return std_match(L,R); end function StdMatch; - function StdMatch (L, R: std_ulogic_vector) return boolean is - begin - return std_match(L,R); - end function StdMatch; function toBuildInfo (din : slv) return BuildInfoRetType is variable ret : BuildInfoRetType; From d42264d7f1e6108c85c7433624aa1d28c8edb03c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 27 Feb 2019 09:03:19 -0800 Subject: [PATCH 25/37] memory overlap bug fix --- .../surf/devices/micron/_AxiMicronMt28ew.py | 13 ++++---- python/surf/devices/micron/_AxiMicronN25Q.py | 31 +++++++++---------- python/surf/devices/micron/_AxiMicronP30.py | 13 ++++---- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index 93b78f5255..0eaaba5a82 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -40,14 +40,13 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.RemoteVariable( - name = "Test", + self.add(pr.LinkVariable( + name = "Test", description = "Scratch Pad tester register", - offset = 0x0C, - bitSize = 32, - bitOffset = 0x00, - base = pr.UInt, - mode = "RW")) + mode = 'RW', + linkedGet = lambda: self._rawRead(offset=0xC), + linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), + )) @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): diff --git a/python/surf/devices/micron/_AxiMicronN25Q.py b/python/surf/devices/micron/_AxiMicronN25Q.py index 5cfa61f700..cb7e13687b 100644 --- a/python/surf/devices/micron/_AxiMicronN25Q.py +++ b/python/surf/devices/micron/_AxiMicronN25Q.py @@ -38,20 +38,19 @@ def __init__(self, self._mcs = misc.McsReader() self._addrMode = addrMode self._progDone = False + self._tryCount = 5 ############################## # Variables ############################## - self.add(pr.RemoteVariable( - name = "Test", + self.add(pr.LinkVariable( + name = "Test", description = "Scratch Pad tester register", - offset = 0x00, - bitSize = 32, - bitOffset = 0x00, - base = pr.UInt, - mode = "RW", - )) - + mode = 'RW', + linkedGet = lambda: self._rawRead(offset=0x0), + linkedSet = lambda value, write: self._rawWrite(offset=0x0,data=value), + )) + ############################## # Constants ############################## @@ -372,21 +371,21 @@ def waitForFlashReady(self): def setModeReg(self): if (self._addrMode): - self._rawWrite(0x04,0x1) + self._rawWrite(offset=0x04,data=0x1,tryCount=self._tryCount) else: - self._rawWrite(0x04,0x0) + self._rawWrite(offset=0x04,data=0x0,tryCount=self._tryCount) def setAddrReg(self,value): - self._rawWrite(0x08,value) + self._rawWrite(offset=0x08,data=value,tryCount=self._tryCount) def setCmdReg(self,value): - self._rawWrite(0x0C,value) + self._rawWrite(offset=0x0C,data=value,tryCount=self._tryCount) def getCmdReg(self): - return (self._rawRead(offset=0x0C)) + return (self._rawRead(offset=0x0C,tryCount=self._tryCount)) def setDataReg(self,values): - self._rawWrite(0x200,values) + self._rawWrite(offset=0x200,data=values,tryCount=self._tryCount) def getDataReg(self): - return (self._rawRead(offset=0x200,numWords=64)) + return (self._rawRead(offset=0x200,numWords=64,tryCount=self._tryCount)) diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 6cb3160da0..7c5df82088 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -40,14 +40,13 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.RemoteVariable( - name = "Test", + self.add(pr.LinkVariable( + name = "Test", description = "Scratch Pad tester register", - offset = 0x0C, - bitSize = 32, - bitOffset = 0x00, - base = pr.UInt, - mode = "RW")) + mode = 'RW', + linkedGet = lambda: self._rawRead(offset=0xC), + linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), + )) @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): From 0c2abad12de61a627a3af1c2accfd62a794fa9c4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 1 Mar 2019 12:49:20 -0800 Subject: [PATCH 26/37] display Scratch Pad tester register as 32-bit HEX value --- python/surf/devices/micron/_AxiMicronMt28ew.py | 1 + python/surf/devices/micron/_AxiMicronN25Q.py | 1 + python/surf/devices/micron/_AxiMicronP30.py | 1 + 3 files changed, 3 insertions(+) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index 0eaaba5a82..e05ab06afc 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -44,6 +44,7 @@ def __init__(self, name = "Test", description = "Scratch Pad tester register", mode = 'RW', + disp = '{:#08x}', linkedGet = lambda: self._rawRead(offset=0xC), linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), )) diff --git a/python/surf/devices/micron/_AxiMicronN25Q.py b/python/surf/devices/micron/_AxiMicronN25Q.py index cb7e13687b..b8d7ed26b6 100644 --- a/python/surf/devices/micron/_AxiMicronN25Q.py +++ b/python/surf/devices/micron/_AxiMicronN25Q.py @@ -47,6 +47,7 @@ def __init__(self, name = "Test", description = "Scratch Pad tester register", mode = 'RW', + disp = '{:#08x}', linkedGet = lambda: self._rawRead(offset=0x0), linkedSet = lambda value, write: self._rawWrite(offset=0x0,data=value), )) diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 7c5df82088..4f80aaa332 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -44,6 +44,7 @@ def __init__(self, name = "Test", description = "Scratch Pad tester register", mode = 'RW', + disp = '{:#08x}', linkedGet = lambda: self._rawRead(offset=0xC), linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), )) From 2266dca9fd5ccbd097eeebed9815d0968bb24413 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 1 Mar 2019 13:57:05 -0800 Subject: [PATCH 27/37] changing Scratch Pad tester register to LocalVariable --- python/surf/devices/micron/_AxiMicronMt28ew.py | 6 +++--- python/surf/devices/micron/_AxiMicronN25Q.py | 6 +++--- python/surf/devices/micron/_AxiMicronP30.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index e05ab06afc..c941d584ea 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -40,13 +40,13 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.LinkVariable( + self.add(pr.LocalVariable( name = "Test", description = "Scratch Pad tester register", mode = 'RW', disp = '{:#08x}', - linkedGet = lambda: self._rawRead(offset=0xC), - linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), + localGet = lambda: self._rawRead(offset=0xC), + localSet = lambda value, write: self._rawWrite(offset=0xC,data=value), )) @self.command(value='',description="Load the .MCS into PROM",) diff --git a/python/surf/devices/micron/_AxiMicronN25Q.py b/python/surf/devices/micron/_AxiMicronN25Q.py index b8d7ed26b6..44aea6abca 100644 --- a/python/surf/devices/micron/_AxiMicronN25Q.py +++ b/python/surf/devices/micron/_AxiMicronN25Q.py @@ -43,13 +43,13 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.LinkVariable( + self.add(pr.LocalVariable( name = "Test", description = "Scratch Pad tester register", mode = 'RW', disp = '{:#08x}', - linkedGet = lambda: self._rawRead(offset=0x0), - linkedSet = lambda value, write: self._rawWrite(offset=0x0,data=value), + localGet = lambda: self._rawRead(offset=0x0), + localSet = lambda value, write: self._rawWrite(offset=0x0,data=value), )) ############################## diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 4f80aaa332..a8041e2814 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -40,13 +40,13 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.LinkVariable( + self.add(pr.LocalVariable( name = "Test", description = "Scratch Pad tester register", mode = 'RW', disp = '{:#08x}', - linkedGet = lambda: self._rawRead(offset=0xC), - linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), + localGet = lambda: self._rawRead(offset=0xC), + localSet = lambda value, write: self._rawWrite(offset=0xC,data=value), )) @self.command(value='',description="Load the .MCS into PROM",) From 8732348858b0c152d7dd559eecd5801026a85c2d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 1 Mar 2019 16:30:17 -0800 Subject: [PATCH 28/37] Use real variables --- python/surf/devices/micron/_AxiMicronP30.py | 88 ++++++++++++++++----- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 7c5df82088..449bf4b725 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -31,7 +31,6 @@ def __init__(self, super().__init__( name = name, description = description, - size = (0x1 << 12), **kwargs) self._mcs = misc.McsReader() @@ -40,13 +39,62 @@ def __init__(self, ############################## # Variables ############################## - self.add(pr.LinkVariable( + self.add(pr.RemoteVariable( name = "Test", description = "Scratch Pad tester register", - mode = 'RW', - linkedGet = lambda: self._rawRead(offset=0xC), - linkedSet = lambda value, write: self._rawWrite(offset=0xC,data=value), - )) + mode = 'RW', + disp = '{:#08x}', + offset = 0x0C + )) + + self.add(pr.RemoteVariable( + name = "BlockSize", + description = "BlockTransferSize", + mode = 'WO', + disp = '{:#08x}', + offset = 0x80, + hidden = True, + )) + + self.add(pr.RemoteVariable( + name = "StartBurst", + description = "Start a burst transfer", + mode = 'WO', + offset = 0x84, + hidden = True, + )) + + self.add(pr.RemoteVariable( + name = "WrData", + description = "Data", + mode = 'WO', + offset = 0x00, + hidden = True, + verify = False, + )) + + self.add(pr.RemoteVariable( + name = "RdData", + description = "Data", + mode = 'RO', + offset = 0x08, + hidden = True, + )) + + self.add(pr.RemoteVariable( + name = "Addr", + description = "Address", + mode = 'RW', + offset = 0x04, + hidden = True, + )) + + self.add(pr.Device( + name = "Block", + offset = 0x400, + hidden = True, + size=256*4)) + @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): @@ -141,7 +189,7 @@ def writeProm(self): # Create a burst data array dataArray = [0] * 256 # Set the block transfer size - self._rawWrite(0x80,0xFF) + self.BlockSize.set(0xFF) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -166,26 +214,26 @@ def writeProm(self): # Check for the last byte if ( cnt == 256 ): # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self.Block._rawWrite(offset=0x00, data=dataArray) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self.StartBurst.set(0x7FFFFFFF&addr) # Check for leftover data if (cnt != 256): # Fill the rest of the data array with ones for i in range(cnt, 256): dataArray[i] = 0xFFFF # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self.Block._rawWrite(offset=0x00, data=dataArray) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self.StartBurst.set(0x7FFFFFFF&addr) # Close the status bar bar.update(self._mcs.size) def verifyProm(self): # Set the data bus - self._rawWrite(offset=0x0, data=0xFFFFFFFF) + self.WrData.set(0xFFFFFFFF) # Set the block transfer size - self._rawWrite(offset=0x80, data=0xFF) + self.BlockSize.set(0xFF) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -201,9 +249,9 @@ def verifyProm(self): # Throttle down printf rate bar.update(0x1FF) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x80000000|addr) + self.StartBurst.set(0x80000000|addr) # Get the data - dataArray = self._rawRead(offset=0x400,numWords=256) + dataArray = self.Block._rawRead(offset=0x00,numWords=256) else: # Get the data for MCS file data |= (int(self._mcs.entry[i][1]) << 8) @@ -219,15 +267,15 @@ def verifyProm(self): # Generic FLASH write Command def _writeToFlash(self, addr, cmd, data): # Set the data bus - self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | (data&0xFFFF)) + self.WrData.set(((cmd&0xFFFF)<< 16) | (data&0xFFFF)) # Set the address bus and initiate the transfer - self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF) + self.Addr.set(addr&0x7FFFFFFF) # Generic FLASH read Command def _readFromFlash(self, addr, cmd): # Set the data bus - self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | 0xFF) + self.WrData.set(((cmd&0xFFFF)<< 16) | 0xFF) # Set the address - self._rawWrite(offset=0x4, data=addr|0x80000000) + self.Addr.set(addr|0x80000000) # Get the read data - return (self._rawRead(offset=0x8)&0xFFFF) + return (self.RdData.get()&0xFFFF) From cd2a7c511ffcf0fecd579157f8e8d193ef5f78d1 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 1 Mar 2019 16:33:12 -0800 Subject: [PATCH 29/37] Make Addr reg write only --- python/surf/devices/micron/_AxiMicronP30.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 449bf4b725..70a16f04da 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -84,7 +84,7 @@ def __init__(self, self.add(pr.RemoteVariable( name = "Addr", description = "Address", - mode = 'RW', + mode = 'WO', offset = 0x04, hidden = True, )) From 30c623013a0c37c551e59b26b52bb74663ba4228 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Mon, 4 Mar 2019 16:38:21 -0800 Subject: [PATCH 30/37] Update --- dsp/fixed/BoxcarIntegrator.vhd | 214 +++++++++++++++++++++++++++++++++ dsp/tb/BoxcarIntegratorTb.vhd | 77 ++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 dsp/fixed/BoxcarIntegrator.vhd create mode 100644 dsp/tb/BoxcarIntegratorTb.vhd diff --git a/dsp/fixed/BoxcarIntegrator.vhd b/dsp/fixed/BoxcarIntegrator.vhd new file mode 100644 index 0000000000..0e1c5f10f9 --- /dev/null +++ b/dsp/fixed/BoxcarIntegrator.vhd @@ -0,0 +1,214 @@ +------------------------------------------------------------------------------- +-- File : BoxcarIntegrator.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Simple boxcar integrator +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +use work.StdRtlPkg.all; + +entity BoxcarIntegrator is + generic ( + TPD_G : time := 1 ns; + DATA_WIDTH_G : positive := 16; + ADDR_WIDTH_G : positive := 10); + port ( + clk : in sl; + rst : in sl; + -- Configuration + intCount : in slv(ADDR_WIDTH_G-1 downto 0); + -- Inbound Interface + ibValid : in sl := '1'; + ibReady : out sl; + ibData : in slv(DATA_WIDTH_G-1 downto 0); + -- Outbound Interface + obValid : out sl; + obData : out slv(DATA_WIDTH_G+ADDR_WIDTH_G-1 downto 0); + obReady : in sl := '1'; + obPeriod : out sl); + +end BoxcarIntegrator; + +architecture rtl of BoxcarIntegrator is + + type State is ( INIT_S, READY_S, ADD_S, SUB_S, OUT_S ); + + type RegType is record intValue : slv(SUM_WIDTH_G-1 downto 0); + state : State; + ibData : slv(DATA_WIDTH_G-1 downto 0); + obPerCnt : slv(ADDR_WIDTH_G-1 downto 0); + intFull : sl; + intPass : sl; + fifoRead : sl; + fifoWrite : sl; + fifoRst : sl; + obData : slv(SUM_WIDTH_G-1 downto 0); + obValid : sl; + obPeriod : sl; + end record RegType; + + constant REG_INIT_C : RegType := ( + state => INIT_S, + ibData => (others=>'0'), + obPerCnt => (others=>'0'), + intFull => '0', + intPass => '0', + fifoRead => '0', + fifoWrite => '0', + fifoRst => '1', + obData => (others=>'0'), + obValid => '0', + obPeriod => '0'); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal fifoDout : slv(DATA_WIDTH_G-1 downto 0); + signal fifoCount : slv(ADDR_WIDTH_G-1 downto 0); + signal fifoFull : sl; + +begin + + comb : process (r, rst, intCount, ibValid, ibData, obRead, intCount, fifoValid, fifoCount, fifoDout, outAck ) is + variable v : RegType; + begin + + v := r; + + -- Init + v.fifoRead := '0'; + v.intFull := '0'; + v.intPass := '0'; + + -- Compute pass through + if intValue = 0 then + v.intPass := '1'; + elsif fifoCount = intValue then + v.intFull := '1'; + end if; + + -- State machine + case r.state is + + -- Init + when INIT_S => + v.state := WAIT_S; + + if r.fifoRst = '0' and fifoFull = '0' then + v.state := READY_S; + end if; + + -- Ready for data + when READY_S => + v.ibReady := '1'; + v.ibValue := ibValue; + + -- Inbound data is valid + if ibValid = '1' then + + -- Pass through + if r.intPass = '1' then + v.obValue := ibData; + v.obValid := '1'; + v.obPeriod := '1'; + v.state := OUT_S; + else + v.state := ADD_S; + v.fifoWrite := '1'; + v.fifoRead := r.intFull; + end if; + end if; + + -- Add + when ADD_S => + v.obValue := r.obValue + r.ibValue; + + if r.fifoRead = '1' then + v.state := SUB_S; + end if; + + -- Sub + when SUB_S => + v.obValue := r.obValue - fifoOut; + v.obValid := '1'; + v.state := OUT_S; + + if r.obPerCnt = perCount then + v.obPeriod := '1'; + v.obPerCnt := (others=>'0'); + else + v.obPeriod := '0'; + v.obPerCnt := r.obPerCnt + 1; + end if; + + -- Output + when OUT_S => + if obReady = '1' then + v.obValid := '0'; + v.obPeriod := '0'; + v.state := READY_S; + end if; + + when others => + v.state := INIT_S; + + end case; + + -- Catch situation where FIFO count exceeds current setting + -- can occur when configuration changes + if rst = '1' or fifoCount > intCount then + v := REG_INIT_C; + end if; + + -- Outputs + ibReady <= v.ibReady; + obValid <= r.obValid; + obData <= r.obData; + obPeriod <= r.obPeriod; + + rin <= v; + + end process; + + seq : process (clk) is + begin + if rising_edge(clk) then + r <= rin after TPD_G; + end if; + end process seq; + + -- Holding FIFO + U_Fifo: entity work.Fifo + generic map ( + TPD_G => TPD_G, + GEN_SYNC_FIFO_G => true, + FWFT_EN_G => false, + DATA_WIDTH_G => DATA_WIDTH_G, + ADDR_WIDTH_G => ADDR_WIDTH_G + ) port map ( + rst => r.fifoRst, + wr_clk => clk, + wr_en => r.fifoWrite, + din => r.ibData, + rd_clk => clk, + rd_en => r.fifoRead, + dout => fifoDout, + rd_data_count => fifoCount, + full => fifoFull + ); + +end rtl; + diff --git a/dsp/tb/BoxcarIntegratorTb.vhd b/dsp/tb/BoxcarIntegratorTb.vhd new file mode 100644 index 0000000000..fd026f1a4e --- /dev/null +++ b/dsp/tb/BoxcarIntegratorTb.vhd @@ -0,0 +1,77 @@ +------------------------------------------------------------------------------- +-- File : BoxcarIntegratorTb.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Simulation Testbed for the BoxcarIntegrator module +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +use work.StdRtlPkg.all; + +entity BoxcarIntegratorTb is end BoxcarIntegratorTb; + +architecture testbed of BoxcarIntegratorTb is + + constant TPD_G : time := 2.5 ns; + + signal clk : sl := '0'; + signal rst : sl := '0'; + + signal ibReady : sl; + signal intCount : slv(10 downto 0); + signal obValid : sl; + signal obPeriod : sl; + signal obData : slv(15 downto 0); + +begin + + U_ClkRst : entity work.ClkRst + generic map ( + CLK_PERIOD_G => 10 ns, + RST_START_DELAY_G => 1 ns, + RST_HOLD_TIME_G => 1 us) + port map ( + clkP => clk, + clkN => open, + rst => rst, + rstL => open); + + process begin + intCount = "0000000000"; + wait for 100 us; + intCount = "0000001000"; -- 8 + wait for 100 us; + intCount = "0000000100"; -- 4 + wait for 100 us; + end process; + + U_BoxcarIntegrator : entity work.BoxcarIntegrator + generic map ( + TPD_G => TPD_G, + DATA_WIDTH_G => 16, + ADDR_WIDTH_G => 10) + port map ( + clk => clk, + rst => rst, + intCount => intCount, + ibValid => '1', + ibReady => ibReady, + ibData => x"000A", + obValid => obValid, + obData => obData, + obReady => '1', + obPeriod => obPeriod); + +end testbed; From d32fe8dd97293f4a1741751b6fee5ef115c83507 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 5 Mar 2019 10:18:29 -0800 Subject: [PATCH 31/37] reverting back to d42264d7f1e6108c85c7433624aa1d28c8edb03c and removing remote variables --- .../surf/devices/micron/_AxiMicronMt28ew.py | 12 --- python/surf/devices/micron/_AxiMicronN25Q.py | 14 +-- python/surf/devices/micron/_AxiMicronP30.py | 89 ++++--------------- 3 files changed, 16 insertions(+), 99 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index c941d584ea..1e0dc6a9d2 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -36,18 +36,6 @@ def __init__(self, self._mcs = misc.McsReader() self._progDone = False - - ############################## - # Variables - ############################## - self.add(pr.LocalVariable( - name = "Test", - description = "Scratch Pad tester register", - mode = 'RW', - disp = '{:#08x}', - localGet = lambda: self._rawRead(offset=0xC), - localSet = lambda value, write: self._rawWrite(offset=0xC,data=value), - )) @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): diff --git a/python/surf/devices/micron/_AxiMicronN25Q.py b/python/surf/devices/micron/_AxiMicronN25Q.py index 44aea6abca..e466cf4331 100644 --- a/python/surf/devices/micron/_AxiMicronN25Q.py +++ b/python/surf/devices/micron/_AxiMicronN25Q.py @@ -38,19 +38,7 @@ def __init__(self, self._mcs = misc.McsReader() self._addrMode = addrMode self._progDone = False - self._tryCount = 5 - - ############################## - # Variables - ############################## - self.add(pr.LocalVariable( - name = "Test", - description = "Scratch Pad tester register", - mode = 'RW', - disp = '{:#08x}', - localGet = lambda: self._rawRead(offset=0x0), - localSet = lambda value, write: self._rawWrite(offset=0x0,data=value), - )) + self._tryCount = 5 ############################## # Constants diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 70a16f04da..30297f8368 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -31,70 +31,11 @@ def __init__(self, super().__init__( name = name, description = description, + size = (0x1 << 12), **kwargs) self._mcs = misc.McsReader() self._progDone = False - - ############################## - # Variables - ############################## - self.add(pr.RemoteVariable( - name = "Test", - description = "Scratch Pad tester register", - mode = 'RW', - disp = '{:#08x}', - offset = 0x0C - )) - - self.add(pr.RemoteVariable( - name = "BlockSize", - description = "BlockTransferSize", - mode = 'WO', - disp = '{:#08x}', - offset = 0x80, - hidden = True, - )) - - self.add(pr.RemoteVariable( - name = "StartBurst", - description = "Start a burst transfer", - mode = 'WO', - offset = 0x84, - hidden = True, - )) - - self.add(pr.RemoteVariable( - name = "WrData", - description = "Data", - mode = 'WO', - offset = 0x00, - hidden = True, - verify = False, - )) - - self.add(pr.RemoteVariable( - name = "RdData", - description = "Data", - mode = 'RO', - offset = 0x08, - hidden = True, - )) - - self.add(pr.RemoteVariable( - name = "Addr", - description = "Address", - mode = 'WO', - offset = 0x04, - hidden = True, - )) - - self.add(pr.Device( - name = "Block", - offset = 0x400, - hidden = True, - size=256*4)) - @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): @@ -189,7 +130,7 @@ def writeProm(self): # Create a burst data array dataArray = [0] * 256 # Set the block transfer size - self.BlockSize.set(0xFF) + self._rawWrite(0x80,0xFF) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -214,26 +155,26 @@ def writeProm(self): # Check for the last byte if ( cnt == 256 ): # Write burst data - self.Block._rawWrite(offset=0x00, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray) # Start a burst transfer - self.StartBurst.set(0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) # Check for leftover data if (cnt != 256): # Fill the rest of the data array with ones for i in range(cnt, 256): dataArray[i] = 0xFFFF # Write burst data - self.Block._rawWrite(offset=0x00, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray) # Start a burst transfer - self.StartBurst.set(0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) # Close the status bar bar.update(self._mcs.size) def verifyProm(self): # Set the data bus - self.WrData.set(0xFFFFFFFF) + self._rawWrite(offset=0x0, data=0xFFFFFFFF) # Set the block transfer size - self.BlockSize.set(0xFF) + self._rawWrite(offset=0x80, data=0xFF) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -249,9 +190,9 @@ def verifyProm(self): # Throttle down printf rate bar.update(0x1FF) # Start a burst transfer - self.StartBurst.set(0x80000000|addr) + self._rawWrite(offset=0x84, data=0x80000000|addr) # Get the data - dataArray = self.Block._rawRead(offset=0x00,numWords=256) + dataArray = self._rawRead(offset=0x400,numWords=256) else: # Get the data for MCS file data |= (int(self._mcs.entry[i][1]) << 8) @@ -267,15 +208,15 @@ def verifyProm(self): # Generic FLASH write Command def _writeToFlash(self, addr, cmd, data): # Set the data bus - self.WrData.set(((cmd&0xFFFF)<< 16) | (data&0xFFFF)) + self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | (data&0xFFFF)) # Set the address bus and initiate the transfer - self.Addr.set(addr&0x7FFFFFFF) + self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF) # Generic FLASH read Command def _readFromFlash(self, addr, cmd): # Set the data bus - self.WrData.set(((cmd&0xFFFF)<< 16) | 0xFF) + self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | 0xFF) # Set the address - self.Addr.set(addr|0x80000000) + self._rawWrite(offset=0x4, data=addr|0x80000000) # Get the read data - return (self.RdData.get()&0xFFFF) + return (self._rawRead(offset=0x8)&0xFFFF) From b88936f63f06daef6e324963a40afd20134e3d94 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 5 Mar 2019 10:19:25 -0800 Subject: [PATCH 32/37] implementing the MmcmEmulation.vhd because no stable in VCS some configurations would hang the simulation --- xilinx/general/tb/MmcmEmulation.vhd | 42 ++++++----------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/xilinx/general/tb/MmcmEmulation.vhd b/xilinx/general/tb/MmcmEmulation.vhd index f0c8972faa..400c8649e5 100644 --- a/xilinx/general/tb/MmcmEmulation.vhd +++ b/xilinx/general/tb/MmcmEmulation.vhd @@ -124,40 +124,14 @@ begin GEN_VEC : for i in 6 downto 0 generate - process is - begin - while (true) loop - --------------------------------------------- - -- Reset and Phasing Up Procedure - --------------------------------------------- - while ((RST = '1') or (phasedUp(i) = '0')) loop - clkOut(i) <= CLKOUT_RST_POLARITY_C(i); - if (RST = '1') then - phasedUp(i) <= '0'; - else - wait for 10 us; - wait until ((CLKIN = '0') or (RST = '1')); - wait until ((CLKIN = '1') or (RST = '1')); - wait for PHASE_OFFSET_C(i); - phasedUp(i) <= '1'; - end if; - end loop; - --------------------------------------------- - -- Clock Procedure - --------------------------------------------- - if (CLKOUT_RST_POLARITY_C(i) = '1') then - clkOut(i) <= '1'; - wait for CLK_HI_CYCLE_C(i); - clkOut(i) <= '0'; - wait for CLK_LO_CYCLE_C(i); - else - clkOut(i) <= '0'; - wait for CLK_LO_CYCLE_C(i); - clkOut(i) <= '1'; - wait for CLK_HI_CYCLE_C(i); - end if; - end loop; - end process; + U_ClkPgp : entity work.ClkRst + generic map ( + CLK_PERIOD_G => CLKOUT_PERIOD_C(i), + RST_START_DELAY_G => 0 ns, + RST_HOLD_TIME_G => 1000 ns) + port map ( + clkP => clkOut(i), + rstL => phasedUp(i)); end generate GEN_VEC; end MmcmEmulation; From c03e68c8dc09f7f2e2a736738ecb90bef745841b Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 5 Mar 2019 10:47:37 -0800 Subject: [PATCH 33/37] Updates --- dsp/fixed/BoxcarIntegrator.vhd | 223 +++++++++++++-------------------- dsp/tb/BoxcarIntegratorTb.vhd | 121 ++++++++++++++++-- 2 files changed, 200 insertions(+), 144 deletions(-) diff --git a/dsp/fixed/BoxcarIntegrator.vhd b/dsp/fixed/BoxcarIntegrator.vhd index 0e1c5f10f9..af1435ac23 100644 --- a/dsp/fixed/BoxcarIntegrator.vhd +++ b/dsp/fixed/BoxcarIntegrator.vhd @@ -28,160 +28,137 @@ entity BoxcarIntegrator is port ( clk : in sl; rst : in sl; - -- Configuration + -- Configuration, intCount intCount : in slv(ADDR_WIDTH_G-1 downto 0); -- Inbound Interface ibValid : in sl := '1'; - ibReady : out sl; ibData : in slv(DATA_WIDTH_G-1 downto 0); -- Outbound Interface obValid : out sl; obData : out slv(DATA_WIDTH_G+ADDR_WIDTH_G-1 downto 0); - obReady : in sl := '1'; + obFull : out sl; obPeriod : out sl); end BoxcarIntegrator; architecture rtl of BoxcarIntegrator is - type State is ( INIT_S, READY_S, ADD_S, SUB_S, OUT_S ); + constant ACCUM_WIDTH_C : positive := (DATA_WIDTH_G+ADDR_WIDTH_G); - type RegType is record intValue : slv(SUM_WIDTH_G-1 downto 0); - state : State; + type RegType is record + obFull : sl; + intCount : slv(ADDR_WIDTH_G-1 downto 0); + rAddr : slv(ADDR_WIDTH_G-1 downto 0); + wAddr : slv(ADDR_WIDTH_G-1 downto 0); + ibValid : sl; ibData : slv(DATA_WIDTH_G-1 downto 0); - obPerCnt : slv(ADDR_WIDTH_G-1 downto 0); - intFull : sl; - intPass : sl; - fifoRead : sl; - fifoWrite : sl; - fifoRst : sl; - obData : slv(SUM_WIDTH_G-1 downto 0); obValid : sl; obPeriod : sl; + obData : slv(ACCUM_WIDTH_C-1 downto 0); end record RegType; constant REG_INIT_C : RegType := ( - state => INIT_S, - ibData => (others=>'0'), - obPerCnt => (others=>'0'), - intFull => '0', - intPass => '0', - fifoRead => '0', - fifoWrite => '0', - fifoRst => '1', - obData => (others=>'0'), - obValid => '0', - obPeriod => '0'); + obFull => '0', + intCount => (others=>'0'), + rAddr => (others=>'0'), + wAddr => (others=>'0'), + ibValid => '0', + ibData => (others=>'0'), + obValid => '0', + obPeriod => '0', + obData => (others=>'0')); signal r : RegType := REG_INIT_C; signal rin : RegType; - signal fifoDout : slv(DATA_WIDTH_G-1 downto 0); - signal fifoCount : slv(ADDR_WIDTH_G-1 downto 0); - signal fifoFull : sl; + signal ramDout : slv(DATA_WIDTH_G-1 downto 0); begin - comb : process (r, rst, intCount, ibValid, ibData, obRead, intCount, fifoValid, fifoCount, fifoDout, outAck ) is + U_RAM : entity work.SimpleDualPortRam + generic map ( + TPD_G => TPD_G, + BRAM_EN_G => true, + DOB_REG_G => false, + DATA_WIDTH_G => DATA_WIDTH_G, + ADDR_WIDTH_G => ADDR_WIDTH_G) + port map ( + -- Port A + clka => clk, + wea => ibValid, + addra => r.wAddr, + dina => r.ibData, + -- Port B + clkb => clk, + addrb => r.rAddr, + doutb => ramDout); + + + comb : process (ibData, ibValid, r, ramDout, rst, intCount) is variable v : RegType; begin - + -- Latch the current value v := r; - -- Init - v.fifoRead := '0'; - v.intFull := '0'; - v.intPass := '0'; + -- Clear period signal + v.obPeriod := '0'; + + -- Input stage, setup addresses + v.ibData := ibData; + v.ibValid := ibValid; + + -- Setup address for next cycle + if ibValid = '1' then + + -- Read address + if r.rAddr = r.intCount then + v.rAddr := (others=>'0'); + else + v.rAddr := r.rAddr + 1; + end if; + + -- Write lags read + v.wAddr := r.rAddr; - -- Compute pass through - if intValue = 0 then - v.intPass := '1'; - elsif fifoCount = intValue then - v.intFull := '1'; end if; - -- State machine - case r.state is - - -- Init - when INIT_S => - v.state := WAIT_S; - - if r.fifoRst = '0' and fifoFull = '0' then - v.state := READY_S; - end if; - - -- Ready for data - when READY_S => - v.ibReady := '1'; - v.ibValue := ibValue; - - -- Inbound data is valid - if ibValid = '1' then - - -- Pass through - if r.intPass = '1' then - v.obValue := ibData; - v.obValid := '1'; - v.obPeriod := '1'; - v.state := OUT_S; - else - v.state := ADD_S; - v.fifoWrite := '1'; - v.fifoRead := r.intFull; - end if; - end if; - - -- Add - when ADD_S => - v.obValue := r.obValue + r.ibValue; - - if r.fifoRead = '1' then - v.state := SUB_S; - end if; - - -- Sub - when SUB_S => - v.obValue := r.obValue - fifoOut; - v.obValid := '1'; - v.state := OUT_S; - - if r.obPerCnt = perCount then - v.obPeriod := '1'; - v.obPerCnt := (others=>'0'); - else - v.obPeriod := '0'; - v.obPerCnt := r.obPerCnt + 1; - end if; - - -- Output - when OUT_S => - if obReady = '1' then - v.obValid := '0'; - v.obPeriod := '0'; - v.state := READY_S; - end if; - - when others => - v.state := INIT_S; - - end case; - - -- Catch situation where FIFO count exceeds current setting - -- can occur when configuration changes - if rst = '1' or fifoCount > intCount then - v := REG_INIT_C; + -- Check for inbound data + if r.ibValid = '1' then + + -- Ready after writing last location + if r.wAddr = r.intCount then + v.obFull := '1'; + v.obPeriod := '1'; + end if; + + -- Update the accumulator + v.obData := r.obData + resize(r.ibData, ACCUM_WIDTH_C); + + -- Check if full + if r.obFull = '1' then + v.obData := v.obData - resize(ramDout, ACCUM_WIDTH_C); + end if; end if; - -- Outputs - ibReady <= v.ibReady; + -- Output registers + v.obValid := r.ibValid; + + -- Outputs obValid <= r.obValid; - obData <= r.obData; + obFull <= r.obFull; obPeriod <= r.obPeriod; + obData <= r.obData; + -- Reset + if rst = '1' or r.intCount /= intCount then + v := REG_INIT_C; + v.intCount := intCount; + end if; + + -- Register the variable for next clock cycle rin <= v; - end process; + end process comb; seq : process (clk) is begin @@ -190,25 +167,5 @@ begin end if; end process seq; - -- Holding FIFO - U_Fifo: entity work.Fifo - generic map ( - TPD_G => TPD_G, - GEN_SYNC_FIFO_G => true, - FWFT_EN_G => false, - DATA_WIDTH_G => DATA_WIDTH_G, - ADDR_WIDTH_G => ADDR_WIDTH_G - ) port map ( - rst => r.fifoRst, - wr_clk => clk, - wr_en => r.fifoWrite, - din => r.ibData, - rd_clk => clk, - rd_en => r.fifoRead, - dout => fifoDout, - rd_data_count => fifoCount, - full => fifoFull - ); - end rtl; diff --git a/dsp/tb/BoxcarIntegratorTb.vhd b/dsp/tb/BoxcarIntegratorTb.vhd index fd026f1a4e..bfef8a48bd 100644 --- a/dsp/tb/BoxcarIntegratorTb.vhd +++ b/dsp/tb/BoxcarIntegratorTb.vhd @@ -29,11 +29,18 @@ architecture testbed of BoxcarIntegratorTb is signal clk : sl := '0'; signal rst : sl := '0'; - signal ibReady : sl; - signal intCount : slv(10 downto 0); - signal obValid : sl; + signal intCount : slv(9 downto 0); signal obPeriod : sl; - signal obData : slv(15 downto 0); + signal obValid : sl; + signal obFull : sl; + signal obData : slv(25 downto 0); + signal validCnt : slv(15 downto 0); + signal validEn : sl; + signal dataIn : slv(15 downto 0); + signal expData0 : slv(25 downto 0); + signal expData1 : slv(25 downto 0); + signal expError : sl; + signal spacing : slv(15 downto 0); begin @@ -48,13 +55,74 @@ begin rst => rst, rstL => open); + process (clk) begin + if rising_edge(clk) then + if rst = '1' then + validCnt <= (others=>'0') after TPD_G; + dataIn <= (others=>'0') after TPD_G; + validEn <= '0'; + else + if validCnt >= spacing then + validCnt <= (others=>'0') after TPD_G; + dataIn <= dataIn + 1 after TPD_G; + validEn <= '1' after TPD_G; + else + validCnt <= validCnt + 1 after TPD_G; + validEn <= '0' after TPD_G; + end if; + end if; + end if; + end process; + process begin - intCount = "0000000000"; + intCount <= toSlv(0,10); + spacing <= toSlv(99,16); + wait for 100 us; + intCount <= toSlv(1,10); + wait for 100 us; + intCount <= toSlv(2,10); + wait for 100 us; + intCount <= toSlv(8,10); + wait for 100 us; + intCount <= toSlv(4,10); wait for 100 us; - intCount = "0000001000"; -- 8 + + intCount <= toSlv(0,10); + spacing <= toSlv(0,16); + wait for 100 us; + intCount <= toSlv(1,10); + wait for 100 us; + intCount <= toSlv(2,10); + wait for 100 us; + intCount <= toSlv(8,10); + wait for 100 us; + intCount <= toSlv(4,10); + wait for 100 us; + + intCount <= toSlv(0,10); + spacing <= toSlv(1,16); wait for 100 us; - intCount = "0000000100"; -- 4 + intCount <= toSlv(1,10); wait for 100 us; + intCount <= toSlv(2,10); + wait for 100 us; + intCount <= toSlv(8,10); + wait for 100 us; + intCount <= toSlv(4,10); + wait for 100 us; + + intCount <= toSlv(0,10); + spacing <= toSlv(2,16); + wait for 100 us; + intCount <= toSlv(1,10); + wait for 100 us; + intCount <= toSlv(2,10); + wait for 100 us; + intCount <= toSlv(8,10); + wait for 100 us; + intCount <= toSlv(4,10); + wait for 100 us; + end process; U_BoxcarIntegrator : entity work.BoxcarIntegrator @@ -66,12 +134,43 @@ begin clk => clk, rst => rst, intCount => intCount, - ibValid => '1', - ibReady => ibReady, - ibData => x"000A", + ibValid => validEn, + ibData => dataIn, obValid => obValid, obData => obData, - obReady => '1', + obFull => obFull, obPeriod => obPeriod); + process (clk) + variable exp : slv(25 downto 0); + variable tmp : slv(15 downto 0); + begin + if rising_edge(clk) then + if rst = '1' then + expData0 <= (others=>'0') after TPD_G; + expData1 <= (others=>'0') after TPD_G; + expError <= '0' after TPD_G; + else + if validEn = '1' then + exp := (others=>'0'); + for i in 0 to conv_integer(intCount) loop + tmp := dataIn - i; + exp := exp + tmp; + end loop; + expData0 <= exp after TPD_G; + end if; + + expData1 <= expData0 after TPD_G; + + if obValid = '1' then + if obFull = '0' or expData1 = obData then + expError <= '0' after TPD_G; + else + expError <= '1' after TPD_G; + end if; + end if; + end if; + end if; + end process; + end testbed; From 3b0ce3d37d42bec3863166b29e5091cdcd09c8d9 Mon Sep 17 00:00:00 2001 From: Ryan Herbst Date: Tue, 5 Mar 2019 10:58:24 -0800 Subject: [PATCH 34/37] Updates --- dsp/fixed/BoxcarIntegrator.vhd | 2 +- dsp/tb/BoxcarIntegratorTb.vhd | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dsp/fixed/BoxcarIntegrator.vhd b/dsp/fixed/BoxcarIntegrator.vhd index af1435ac23..8c1140a1d5 100644 --- a/dsp/fixed/BoxcarIntegrator.vhd +++ b/dsp/fixed/BoxcarIntegrator.vhd @@ -28,7 +28,7 @@ entity BoxcarIntegrator is port ( clk : in sl; rst : in sl; - -- Configuration, intCount + -- Configuration, intCount is 0 based, 0 = 1, 1 = 2, 1023 = 1024 intCount : in slv(ADDR_WIDTH_G-1 downto 0); -- Inbound Interface ibValid : in sl := '1'; diff --git a/dsp/tb/BoxcarIntegratorTb.vhd b/dsp/tb/BoxcarIntegratorTb.vhd index bfef8a48bd..995b19b9a1 100644 --- a/dsp/tb/BoxcarIntegratorTb.vhd +++ b/dsp/tb/BoxcarIntegratorTb.vhd @@ -86,6 +86,8 @@ begin wait for 100 us; intCount <= toSlv(4,10); wait for 100 us; + intCount <= toSlv(1023,10); + wait for 4000 us; intCount <= toSlv(0,10); spacing <= toSlv(0,16); @@ -98,6 +100,8 @@ begin wait for 100 us; intCount <= toSlv(4,10); wait for 100 us; + intCount <= toSlv(1023,10); + wait for 4000 us; intCount <= toSlv(0,10); spacing <= toSlv(1,16); @@ -110,6 +114,8 @@ begin wait for 100 us; intCount <= toSlv(4,10); wait for 100 us; + intCount <= toSlv(1023,10); + wait for 4000 us; intCount <= toSlv(0,10); spacing <= toSlv(2,16); @@ -122,6 +128,8 @@ begin wait for 100 us; intCount <= toSlv(4,10); wait for 100 us; + intCount <= toSlv(1023,10); + wait for 4000 us; end process; From 93fc7e73801ddbab4cb02077050b8dbd0f43bdc6 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 5 Mar 2019 11:26:40 -0800 Subject: [PATCH 35/37] wrapping the BoxcarFilter around the BoxcarIntegrator --- dsp/fixed/BoxcarFilter.vhd | 132 ++++++++----------------------------- 1 file changed, 27 insertions(+), 105 deletions(-) diff --git a/dsp/fixed/BoxcarFilter.vhd b/dsp/fixed/BoxcarFilter.vhd index b9d7478d93..c7013b73d9 100644 --- a/dsp/fixed/BoxcarFilter.vhd +++ b/dsp/fixed/BoxcarFilter.vhd @@ -26,121 +26,43 @@ entity BoxcarFilter is DATA_WIDTH_G : positive := 16; ADDR_WIDTH_G : positive := 10); port ( - clk : in sl; - rst : in sl; + clk : in sl; + rst : in sl; -- Inbound Interface - ibValid : in sl := '1'; - ibData : in slv(DATA_WIDTH_G-1 downto 0); + ibValid : in sl := '1'; + ibData : in slv(DATA_WIDTH_G-1 downto 0); -- Outbound Interface - obValid : out sl; - obData : out slv(DATA_WIDTH_G-1 downto 0)); + obValid : out sl; + obData : out slv(DATA_WIDTH_G-1 downto 0); + obFull : out sl; + obPeriod : out sl); end BoxcarFilter; -architecture rtl of BoxcarFilter is +architecture mapping of BoxcarFilter is - constant ACCUM_WIDTH_C : positive := (DATA_WIDTH_G+ADDR_WIDTH_G); - constant MAX_CNT_C : slv(ADDR_WIDTH_G-1 downto 0) := (others => '1'); - - type RegType is record - init : sl; - accum : slv(ACCUM_WIDTH_C-1 downto 0); - addr : slv(ADDR_WIDTH_G-1 downto 0); - obValid : sl; - obData : slv(DATA_WIDTH_G-1 downto 0); - end record RegType; - constant REG_INIT_C : RegType := ( - init => '0', - accum => (others => '0'), - addr => MAX_CNT_C, - obValid => '0', - obData => (others => '0')); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal waddr : slv(ADDR_WIDTH_G-1 downto 0); - signal raddr : slv(ADDR_WIDTH_G-1 downto 0); - signal ramDout : slv(DATA_WIDTH_G-1 downto 0); + signal intData : slv(DATA_WIDTH_G+ADDR_WIDTH_G-1 downto 0); begin - U_RAM : entity work.SimpleDualPortRam + U_Integrator : entity work.BoxcarIntegrator generic map ( TPD_G => TPD_G, - BRAM_EN_G => true, - DOB_REG_G => false, DATA_WIDTH_G => DATA_WIDTH_G, ADDR_WIDTH_G => ADDR_WIDTH_G) port map ( - -- Port A - clka => clk, - wea => ibValid, - addra => waddr, - dina => ibData, - -- Port B - clkb => clk, - addrb => raddr, - doutb => ramDout); - - comb : process (ibData, ibValid, r, ramDout, rst) is - variable v : RegType; - begin - -- Latch the current value - v := r; - - -- Reset strobes - v.obValid := '0'; - - -- Check for inbound data - if (ibValid = '1') then - - -- Update the accumulator - v.accum := r.accum + resize(ibData, ACCUM_WIDTH_C); - - -- Check if initialized - if (r.init = '1') then - - -- Update the accumulator - v.accum := v.accum - resize(ramDout, ACCUM_WIDTH_C); - - -- Forward the result - v.obValid := '1'; - v.obData := v.accum(ACCUM_WIDTH_C-1 downto ADDR_WIDTH_G); -- Truncate the accumulator - - end if; - - -- Increment the address - v.addr := r.addr + 1; - - -- Check if the ram has been initialized - if (v.addr = MAX_CNT_C) then - -- Set the flag - v.init := '1'; - end if; - - end if; - - -- Outputs - waddr <= v.addr; - raddr <= v.addr + 1; -- Look ahead 1 sample - obValid <= r.obValid; - obData <= r.obData; - - -- Reset - if (rst = '1') then - v := REG_INIT_C; - end if; - - -- Register the variable for next clock cycle - rin <= v; - - end process comb; - - seq : process (clk) is - begin - if rising_edge(clk) then - r <= rin after TPD_G; - end if; - end process seq; - -end rtl; + clk => clk, + rst => rst, + -- Configuration, intCount is 0 based, 0 = 1, 1 = 2, 1023 = 1024 + intCount => (others => '1'), + -- Inbound Interface + ibValid => ibValid, + ibData => ibData, + -- Outbound Interface + obValid => obValid, + obData => intData, + obFull => obFull, + obPeriod => obPeriod); + + obData <= intData(DATA_WIDTH_G+ADDR_WIDTH_G-1 downto ADDR_WIDTH_G); -- Truncate the integrator output (power of 2 divide) + +end mapping; From 64d7af1b7a30c1ab95db35b95fd1485821864dfe Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 5 Mar 2019 11:46:28 -0800 Subject: [PATCH 36/37] addin _tryCount to _AxiMicronMt28ew.py & _AxiMicronP30.py --- .../surf/devices/micron/_AxiMicronMt28ew.py | 27 ++++++++--------- python/surf/devices/micron/_AxiMicronP30.py | 29 ++++++++++--------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index 1e0dc6a9d2..1dd4bd7e48 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -36,6 +36,7 @@ def __init__(self, self._mcs = misc.McsReader() self._progDone = False + self._tryCount = 5 @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): @@ -123,7 +124,7 @@ def writeProm(self): # Create a burst data array dataArray = [0] * 256 # Set the block transfer size - self._rawWrite(0x80,0xFF) + self._rawWrite(0x80,0xFF,tryCount=self._tryCount) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -148,18 +149,18 @@ def writeProm(self): # Check for the last byte if ( cnt == 256 ): # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray,tryCount=self._tryCount) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr,tryCount=self._tryCount) # Check for leftover data if (cnt != 256): # Fill the rest of the data array with ones for i in range(cnt, 256): dataArray[i] = 0xFFFF # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray,tryCount=self._tryCount) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr,tryCount=self._tryCount) # Close the status bar bar.update(self._mcs.size) @@ -167,9 +168,9 @@ def verifyProm(self): # Reset the PROM self._resetCmd() # Set the data bus - self._rawWrite(offset=0x0, data=0xFFFFFFFF) + self._rawWrite(offset=0x0, data=0xFFFFFFFF,tryCount=self._tryCount) # Set the block transfer size - self._rawWrite(offset=0x80, data=0xFF) + self._rawWrite(offset=0x80, data=0xFF,tryCount=self._tryCount) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -185,9 +186,9 @@ def verifyProm(self): # Throttle down printf rate bar.update(0x1FF) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x80000000|addr) + self._rawWrite(offset=0x84, data=0x80000000|addr,tryCount=self._tryCount) # Get the data - dataArray = self._rawRead(offset=0x400,numWords=256) + dataArray = self._rawRead(offset=0x400,numWords=256,tryCount=self._tryCount) else: # Get the data for MCS file data |= (int(self._mcs.entry[i][1]) << 8) @@ -203,13 +204,13 @@ def verifyProm(self): # Generic FLASH write Command def _writeToFlash(self, addr, data): # Set the data bus - self._rawWrite(offset=0x0, data=data) + self._rawWrite(offset=0x0, data=data,tryCount=self._tryCount) # Set the address bus and initiate the transfer - self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF) + self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF,tryCount=self._tryCount) # Generic FLASH read Command def _readFromFlash(self, addr): # Set the address - self._rawWrite(offset=0x4, data=addr|0x80000000) + self._rawWrite(offset=0x4, data=addr|0x80000000,tryCount=self._tryCount) # Get the read data - return (self._rawRead(offset=0x8)&0xFFFF) + return (self._rawRead(offset=0x8,tryCount=self._tryCount)&0xFFFF) diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index 30297f8368..bf0964eb66 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -36,6 +36,7 @@ def __init__(self, self._mcs = misc.McsReader() self._progDone = False + self._tryCount = 5 @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): @@ -130,7 +131,7 @@ def writeProm(self): # Create a burst data array dataArray = [0] * 256 # Set the block transfer size - self._rawWrite(0x80,0xFF) + self._rawWrite(0x80,0xFF,tryCount=self._tryCount) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -155,26 +156,26 @@ def writeProm(self): # Check for the last byte if ( cnt == 256 ): # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray,tryCount=self._tryCount) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr,tryCount=self._tryCount) # Check for leftover data if (cnt != 256): # Fill the rest of the data array with ones for i in range(cnt, 256): dataArray[i] = 0xFFFF # Write burst data - self._rawWrite(offset=0x400, data=dataArray) + self._rawWrite(offset=0x400, data=dataArray,tryCount=self._tryCount) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr) + self._rawWrite(offset=0x84, data=0x7FFFFFFF&addr,tryCount=self._tryCount) # Close the status bar bar.update(self._mcs.size) def verifyProm(self): # Set the data bus - self._rawWrite(offset=0x0, data=0xFFFFFFFF) + self._rawWrite(offset=0x0, data=0xFFFFFFFF,tryCount=self._tryCount) # Set the block transfer size - self._rawWrite(offset=0x80, data=0xFF) + self._rawWrite(offset=0x80, data=0xFF,tryCount=self._tryCount) # Setup the status bar with click.progressbar( length = self._mcs.size, @@ -190,9 +191,9 @@ def verifyProm(self): # Throttle down printf rate bar.update(0x1FF) # Start a burst transfer - self._rawWrite(offset=0x84, data=0x80000000|addr) + self._rawWrite(offset=0x84, data=0x80000000|addr,tryCount=self._tryCount) # Get the data - dataArray = self._rawRead(offset=0x400,numWords=256) + dataArray = self._rawRead(offset=0x400,numWords=256,tryCount=self._tryCount) else: # Get the data for MCS file data |= (int(self._mcs.entry[i][1]) << 8) @@ -208,15 +209,15 @@ def verifyProm(self): # Generic FLASH write Command def _writeToFlash(self, addr, cmd, data): # Set the data bus - self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | (data&0xFFFF)) + self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | (data&0xFFFF),tryCount=self._tryCount) # Set the address bus and initiate the transfer - self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF) + self._rawWrite(offset=0x4,data=addr&0x7FFFFFFF,tryCount=self._tryCount) # Generic FLASH read Command def _readFromFlash(self, addr, cmd): # Set the data bus - self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | 0xFF) + self._rawWrite(offset=0x0, data=((cmd&0xFFFF)<< 16) | 0xFF,tryCount=self._tryCount) # Set the address - self._rawWrite(offset=0x4, data=addr|0x80000000) + self._rawWrite(offset=0x4, data=addr|0x80000000,tryCount=self._tryCount) # Get the read data - return (self._rawRead(offset=0x8)&0xFFFF) + return (self._rawRead(offset=0x8,tryCount=self._tryCount)&0xFFFF) From 692cf89877863aabf512f78a2febff1375123b69 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 5 Mar 2019 11:59:39 -0800 Subject: [PATCH 37/37] passing tryCount in to the constructors --- python/surf/devices/micron/_AxiMicronMt28ew.py | 3 ++- python/surf/devices/micron/_AxiMicronN25Q.py | 3 ++- python/surf/devices/micron/_AxiMicronP30.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python/surf/devices/micron/_AxiMicronMt28ew.py b/python/surf/devices/micron/_AxiMicronMt28ew.py index 1dd4bd7e48..a12dfcdd17 100644 --- a/python/surf/devices/micron/_AxiMicronMt28ew.py +++ b/python/surf/devices/micron/_AxiMicronMt28ew.py @@ -27,6 +27,7 @@ class AxiMicronMt28ew(pr.Device): def __init__(self, name = "AxiMicronMt28ew", description = "AXI-Lite Micron MT28EW PROM", + tryCount = 5, **kwargs): super().__init__( name = name, @@ -36,7 +37,7 @@ def __init__(self, self._mcs = misc.McsReader() self._progDone = False - self._tryCount = 5 + self._tryCount = tryCount @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg): diff --git a/python/surf/devices/micron/_AxiMicronN25Q.py b/python/surf/devices/micron/_AxiMicronN25Q.py index e466cf4331..6446694ad1 100644 --- a/python/surf/devices/micron/_AxiMicronN25Q.py +++ b/python/surf/devices/micron/_AxiMicronN25Q.py @@ -28,6 +28,7 @@ def __init__(self, name = "AxiMicronN25Q", description = "AXI-Lite Micron N25Q and Micron MT25Q PROM", addrMode = False, # False = 24-bit Address mode, True = 32-bit Address Mode + tryCount = 5, **kwargs): super().__init__( name = name, @@ -38,7 +39,7 @@ def __init__(self, self._mcs = misc.McsReader() self._addrMode = addrMode self._progDone = False - self._tryCount = 5 + self._tryCount = tryCount ############################## # Constants diff --git a/python/surf/devices/micron/_AxiMicronP30.py b/python/surf/devices/micron/_AxiMicronP30.py index bf0964eb66..468905686c 100644 --- a/python/surf/devices/micron/_AxiMicronP30.py +++ b/python/surf/devices/micron/_AxiMicronP30.py @@ -27,6 +27,7 @@ class AxiMicronP30(pr.Device): def __init__(self, name = "AxiMicronP30", description = "AXI-Lite Micron P30 PROM", + tryCount = 5, **kwargs): super().__init__( name = name, @@ -36,7 +37,7 @@ def __init__(self, self._mcs = misc.McsReader() self._progDone = False - self._tryCount = 5 + self._tryCount = tryCount @self.command(value='',description="Load the .MCS into PROM",) def LoadMcsFile(arg):