From e63f906a9b343b59764a0f8f82f88b10459b3a38 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Thu, 25 Oct 2018 15:01:51 -0700 Subject: [PATCH 01/92] restoring the old name for the 7 series variant --- .../rtl/{Ad9249Readout7S.vhd => Ad9249ReadoutGroup.vhd} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename devices/AnalogDevices/ad9249/7Series/rtl/{Ad9249Readout7S.vhd => Ad9249ReadoutGroup.vhd} (99%) diff --git a/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249Readout7S.vhd b/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd similarity index 99% rename from devices/AnalogDevices/ad9249/7Series/rtl/Ad9249Readout7S.vhd rename to devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd index 5baf46a118..0552dcf07d 100644 --- a/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249Readout7S.vhd +++ b/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd @@ -31,7 +31,7 @@ use work.AxiLitePkg.all; use work.AxiStreamPkg.all; use work.Ad9249Pkg.all; -entity Ad9249ReadoutGroup7S is +entity Ad9249ReadoutGroup is generic ( TPD_G : time := 1 ns; NUM_CHANNELS_G : natural range 1 to 8 := 8; @@ -60,10 +60,10 @@ entity Ad9249ReadoutGroup7S is adcStreamClk : in sl; adcStreams : out AxiStreamMasterArray(NUM_CHANNELS_G-1 downto 0) := (others => axiStreamMasterInit((false, 2, 8, 0, TKEEP_NORMAL_C, 0, TUSER_NORMAL_C)))); -end Ad9249ReadoutGroup7S; +end Ad9249ReadoutGroup; -- Define architecture -architecture rtl of Ad9249ReadoutGroup7S is +architecture rtl of Ad9249ReadoutGroup is ------------------------------------------------------------------------------------------------- -- AXIL Registers From be607bb76c62529812c8878c5dc22b991760089d Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Mon, 29 Oct 2018 15:12:02 -0700 Subject: [PATCH 02/92] added optional ADC signal inversion --- .../ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd | 26 ++++++++++++++++--- .../UltraScale/rtl/Ad9249ReadoutGroup.vhd | 26 ++++++++++++++++--- python/surf/devices/analog_devices/_ad9249.py | 10 +++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd b/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd index 0552dcf07d..3e4aa41427 100644 --- a/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd +++ b/devices/AnalogDevices/ad9249/7Series/rtl/Ad9249ReadoutGroup.vhd @@ -78,6 +78,7 @@ architecture rtl of Ad9249ReadoutGroup is readoutDebug0 : slv16Array(NUM_CHANNELS_G-1 downto 0); readoutDebug1 : slv16Array(NUM_CHANNELS_G-1 downto 0); lockedCountRst : sl; + invert : sl; end record; constant AXIL_REG_INIT_C : AxilRegType := ( @@ -89,7 +90,9 @@ architecture rtl of Ad9249ReadoutGroup is freezeDebug => '0', readoutDebug0 => (others => (others => '0')), readoutDebug1 => (others => (others => '0')), - lockedCountRst => '0'); + lockedCountRst => '0', + invert => '0' + ); signal lockedSync : sl; signal lockedFallCount : slv(15 downto 0); @@ -142,6 +145,8 @@ architecture rtl of Ad9249ReadoutGroup is signal debugDataValid : sl; signal debugDataOut : slv(NUM_CHANNELS_G*16-1 downto 0); signal debugDataTmp : slv16Array(NUM_CHANNELS_G-1 downto 0); + + signal invertSync : sl; begin ------------------------------------------------------------------------------------------------- @@ -186,6 +191,15 @@ begin rst => axilRst, dataIn => adcFrame, dataOut => adcFrameSync); + + Synchronizer_2 : entity work.Synchronizer + generic map ( + TPD_G => TPD_G, + STAGES_G => 2) + port map ( + clk => adcBitClkR, + dataIn => axilR.invert, + dataOut => invertSync); ------------------------------------------------------------------------------------------------- -- AXIL Interface @@ -232,6 +246,8 @@ begin axiSlaveRegisterR(axilEp, X"30", 16, lockedSync); axiSlaveRegisterR(axilEp, X"34", 0, adcFrameSync); axiSlaveRegister(axilEp, X"38", 0, v.lockedCountRst); + + axiSlaveRegister(axilEp, X"40", 0, v.invert); -- Debug registers. Output the last 2 words received for i in 0 to NUM_CHANNELS_G-1 loop @@ -375,7 +391,7 @@ begin ------------------------------------------------------------------------------------------------- -- ADC Bit Clocked Logic ------------------------------------------------------------------------------------------------- - adcComb : process (adcData, adcFrame, adcR) is + adcComb : process (adcData, adcFrame, adcR, invertSync) is variable v : AdcRegType; begin v := adcR; @@ -405,7 +421,11 @@ begin for i in NUM_CHANNELS_G-1 downto 0 loop if (adcR.locked = '1' and adcFrame = "11111110000000") then -- Locked, output adc data - v.fifoWrData(i) := "00" & adcData(i); + if invertSync = '1' then + v.fifoWrData(i) := "00" & (x"3FFF" - adcData(i)); + else + v.fifoWrData(i) := "00" & adcData(i); + end if; else -- Not locked v.fifoWrData(i) := (others => '1'); --"10" & "00000000000000"; diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd index 8674bf5922..1c224726ec 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd @@ -87,6 +87,7 @@ architecture rtl of Ad9249ReadoutGroup is readoutDebug0 : slv16Array(NUM_CHANNELS_G-1 downto 0); readoutDebug1 : slv16Array(NUM_CHANNELS_G-1 downto 0); lockedCountRst : sl; + invert : sl; end record; constant AXIL_REG_INIT_C : AxilRegType := ( @@ -98,7 +99,9 @@ architecture rtl of Ad9249ReadoutGroup is freezeDebug => '0', readoutDebug0 => (others => (others => '0')), readoutDebug1 => (others => (others => '0')), - lockedCountRst => '0'); + lockedCountRst => '0', + invert => '0' + ); signal lockedSync : sl; signal lockedFallCount : slv(15 downto 0); @@ -162,6 +165,8 @@ architecture rtl of Ad9249ReadoutGroup is signal frameDelay : slv(8 downto 0); signal frameDelaySet : sl; + + signal invertSync : sl; attribute keep of adcBitClkRD4 : signal is "true"; attribute keep of adcBitClkR : signal is "true"; @@ -211,6 +216,15 @@ begin rst => axilRst, dataIn => adcFrame, dataOut => adcFrameSync); + + Synchronizer_2 : entity work.Synchronizer + generic map ( + TPD_G => TPD_G, + STAGES_G => 2) + port map ( + clk => adcBitClkR, + dataIn => axilR.invert, + dataOut => invertSync); ------------------------------------------------------------------------------------------------- -- AXIL Interface @@ -258,6 +272,8 @@ begin axiSlaveRegisterR(axilEp, X"30", 16, lockedSync); axiSlaveRegisterR(axilEp, X"34", 0, adcFrameSync); axiSlaveRegister(axilEp, X"38", 0, v.lockedCountRst); + + axiSlaveRegister(axilEp, X"40", 0, v.invert); -- Debug registers. Output the last 2 words received for i in 0 to NUM_CHANNELS_G-1 loop @@ -509,7 +525,7 @@ begin ------------------------------------------------------------------------------------------------- -- ADC Bit Clocked Logic ------------------------------------------------------------------------------------------------- - adcComb : process (adcData, adcFrame, adcR) is + adcComb : process (adcData, adcFrame, adcR, invertSync) is variable v : AdcRegType; begin v := adcR; @@ -543,7 +559,11 @@ begin for i in NUM_CHANNELS_G-1 downto 0 loop if (adcR.locked = '1' and adcFrame = FRAME_PATTERN_C) then -- Locked, output adc data - v.fifoWrData(i) := "00" & adcData(i); + if invertSync = '1' then + v.fifoWrData(i) := "00" & (x"3FFF" - adcData(i)); + else + v.fifoWrData(i) := "00" & adcData(i); + end if; else -- Not locked v.fifoWrData(i) := (others => '1'); --"10" & "00000000000000"; diff --git a/python/surf/devices/analog_devices/_ad9249.py b/python/surf/devices/analog_devices/_ad9249.py index 4513b0298c..2c4e4d5b8a 100644 --- a/python/surf/devices/analog_devices/_ad9249.py +++ b/python/surf/devices/analog_devices/_ad9249.py @@ -297,6 +297,16 @@ def __init__(self, base = pr.UInt, mode = 'RO', )) + + self.add(pr.RemoteVariable( + name = 'Invert', + description = 'Optional ADC data inversion (offset binary only)', + offset = 0x40, + bitSize = 1, + bitOffset = 0, + base = pr.Bool, + mode = 'RW', + )) for i in range(channels): self.add(pr.RemoteVariable( From 6c916611df2bcfa34e9634e94703c7719bf5488e Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Thu, 8 Nov 2018 18:54:55 -0800 Subject: [PATCH 03/92] optional asic mmask input --- protocols/saci/rtl/SaciPrepRdout.vhd | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/protocols/saci/rtl/SaciPrepRdout.vhd b/protocols/saci/rtl/SaciPrepRdout.vhd index 7e15219831..563988843b 100644 --- a/protocols/saci/rtl/SaciPrepRdout.vhd +++ b/protocols/saci/rtl/SaciPrepRdout.vhd @@ -27,6 +27,7 @@ entity SaciPrepRdout is generic ( TPD_G : time := 1 ns; MASK_REG_ADDR_G : slv(31 downto 0) := x"00000034"; + MASK_REG_READ_G : boolean := true; SACI_BASE_ADDR_G : slv(31 downto 0) := x"02000000"; SACI_NUM_CHIPS_G : natural range 1 to 4 := 4 ); @@ -39,16 +40,19 @@ entity SaciPrepRdout is prepRdoutAck : out sl; -- Optional AXI lite slave port for status readout - sAxilWriteMaster : in AxiLiteWriteMasterType; + sAxilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; sAxilWriteSlave : out AxiLiteWriteSlaveType; - sAxilReadMaster : in AxiLiteReadMasterType; + sAxilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; sAxilReadSlave : out AxiLiteReadSlaveType; -- AXI lite master port for command issue mAxilWriteMaster : out AxiLiteWriteMasterType; mAxilWriteSlave : in AxiLiteWriteSlaveType; mAxilReadMaster : out AxiLiteReadMasterType; - mAxilReadSlave : in AxiLiteReadSlaveType + mAxilReadSlave : in AxiLiteReadSlaveType; + + -- optianally provide ASIC mask + asicMask : in slv(SACI_NUM_CHIPS_G-1 downto 0) := (others=>'0') ); end SaciPrepRdout; @@ -98,7 +102,7 @@ architecture rtl of SaciPrepRdout is begin - comb : process (axilRst, sAxilReadMaster, sAxilWriteMaster, mAxilReadSlave, mAxilWriteSlave, r, prepRdoutReq) is + comb : process (axilRst, sAxilReadMaster, sAxilWriteMaster, mAxilReadSlave, mAxilWriteSlave, r, prepRdoutReq, asicMask) is variable v : RegType; variable regCon : AxiLiteEndPointType; begin @@ -127,7 +131,12 @@ begin -- If we see a multi-pixel write request, handle it if (prepRdoutReq = '1') then + if MASK_REG_READ_G = true then v.state := S_READ_C; + else + v.asicMask := asicMask; + v.state := S_IS_ASIC_C; + end if; end if; -- Read the ASIC mask From 7b886b00ef9fd01e1796f3908db82c46e01ce113 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Sat, 10 Nov 2018 17:54:01 -0800 Subject: [PATCH 04/92] Fix to allow issue commands to remaining ASICs when access to one of them failed --- protocols/saci/rtl/SaciPrepRdout.vhd | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/protocols/saci/rtl/SaciPrepRdout.vhd b/protocols/saci/rtl/SaciPrepRdout.vhd index 563988843b..6856969259 100644 --- a/protocols/saci/rtl/SaciPrepRdout.vhd +++ b/protocols/saci/rtl/SaciPrepRdout.vhd @@ -239,14 +239,8 @@ begin if v.mAxilWriteMaster.awvalid = '0' and v.mAxilWriteMaster.wvalid = '0' and v.mAxilWriteMaster.bready = '0' then - - if mAxilWriteSlave.bresp /= AXI_RESP_OK_C or r.timer = 0 then - v.state := S_IDLE_C; - else - v.asicCnt := r.asicCnt + 1; - v.state := S_IS_ASIC_C; - end if; - + v.asicCnt := r.asicCnt + 1; + v.state := S_IS_ASIC_C; end if; end case; From 51ac32a68cecdeffdf2ab9df296ca9aa9cfa1821 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Sat, 10 Nov 2018 17:54:26 -0800 Subject: [PATCH 05/92] added some missing registers required for debugging --- python/surf/devices/analog_devices/_ad9249.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/python/surf/devices/analog_devices/_ad9249.py b/python/surf/devices/analog_devices/_ad9249.py index 2c4e4d5b8a..764a8ffb89 100644 --- a/python/surf/devices/analog_devices/_ad9249.py +++ b/python/surf/devices/analog_devices/_ad9249.py @@ -181,6 +181,42 @@ def __init__(self, 0: 'Offset Binary', }, )) + + self.add(pr.RemoteVariable( + name = 'UserPatt1Lsb', + offset = (0x19*4), + bitSize = 8, + bitOffset = 0, + )) + + self.add(pr.RemoteVariable( + name = 'UserPatt1Msb', + offset = (0x1A*4), + bitSize = 8, + bitOffset = 0, + )) + + self.add(pr.RemoteVariable( + name = 'UserPatt2Lsb', + offset = (0x1B*4), + bitSize = 8, + bitOffset = 0, + )) + + self.add(pr.RemoteVariable( + name = 'UserPatt2Msb', + offset = (0x1C*4), + bitSize = 8, + bitOffset = 0, + )) + + self.add(pr.RemoteVariable( + name = 'LvdsLsbFirst', + offset = (0x21*4), + bitSize = 1, + bitOffset = 7, + base = pr.Bool, + )) class Ad9249ChipConfig(pr.Device): def __init__(self, From 56a9ced1df3e0d93f78b543eaf65c37a2d314899 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Sat, 10 Nov 2018 17:55:21 -0800 Subject: [PATCH 06/92] fixed ultrascale implementation --- .../AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd | 2 +- .../AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd index e972804a5d..7aab13e83e 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd @@ -140,7 +140,7 @@ architecture rtl of Ad9249Deserializer is begin - adcData <= bitReverse(adcDv7R.masterAdcData(13 downto 7)) & bitReverse(adcDv7R.masterAdcData(6 downto 0)) when BIT_REV_G = '1' + adcData <= bitReverse(adcDv7R.masterAdcData(6 downto 0)) & bitReverse(adcDv7R.masterAdcData(13 downto 7)) when BIT_REV_G = '1' else adcDv7R.masterAdcData; diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd index 1c224726ec..c11d309e73 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd @@ -72,7 +72,7 @@ architecture rtl of Ad9249ReadoutGroup is attribute keep : string; - constant FRAME_PATTERN_C : slv(13 downto 0) := "00000001111111"; + constant FRAME_PATTERN_C : slv(13 downto 0) := "11111110000000"; ------------------------------------------------------------------------------------------------- -- AXIL Registers From accf0d4e76d2c627c5807020178a85e33bf8e27d Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Mon, 26 Nov 2018 12:21:10 -0800 Subject: [PATCH 07/92] add an option to move sampling time --- base/general/rtl/DS2411Core.vhd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/base/general/rtl/DS2411Core.vhd b/base/general/rtl/DS2411Core.vhd index 4f9bc646c2..3e6fdafe73 100644 --- a/base/general/rtl/DS2411Core.vhd +++ b/base/general/rtl/DS2411Core.vhd @@ -30,7 +30,8 @@ entity DS2411Core is TPD_G : time := 1 ns; SIMULATION_G : boolean := false; SIM_OUTPUT_G : slv(63 downto 0) := x"0123456789ABCDEF"; - CLK_PERIOD_G : real := 6.4E-9); --units of seconds + CLK_PERIOD_G : real := 6.4E-9; --units of seconds + SMPL_TIME_G : real := 13.1E-6); --move sample time port ( -- Clock & Reset Signals clk : in sl; @@ -271,7 +272,7 @@ begin nxtState <= curState; -- Sample data at 13.1uS - elsif timeCnt = toSlv(getTimeRatio(13.1E-6, CLK_PERIOD_G), 32) then + elsif timeCnt = toSlv(getTimeRatio(SMPL_TIME_G, CLK_PERIOD_G), 32) then setOutLow <= '0'; bitCntEn <= '0'; timeCntRst <= '0'; From 2ba953e10654266071c79cdbc4e24e6a419e38d5 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Wed, 5 Dec 2018 22:33:07 -0800 Subject: [PATCH 08/92] optional bus arbitration handshake --- protocols/saci/rtl/AxiLiteSaciMaster.vhd | 69 +++++++++++++++--------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/protocols/saci/rtl/AxiLiteSaciMaster.vhd b/protocols/saci/rtl/AxiLiteSaciMaster.vhd index 0a4dc8536d..10a3ffdd63 100644 --- a/protocols/saci/rtl/AxiLiteSaciMaster.vhd +++ b/protocols/saci/rtl/AxiLiteSaciMaster.vhd @@ -39,6 +39,9 @@ entity AxiLiteSaciMaster is saciCmd : out sl; saciSelL : out slv(SACI_NUM_CHIPS_G-1 downto 0); saciRsp : in slv(ite(SACI_RSP_BUSSED_G, 0, SACI_NUM_CHIPS_G-1) downto 0); + -- Optional SACI bus arbitration + saciBusReq : out sl; + saciBusGr : in sl := '1'; -- AXI-Lite Register Interface axilClk : in sl; axilRst : in sl; @@ -60,6 +63,7 @@ architecture rtl of AxiLiteSaciMaster is type RegType is record state : StateType; + saciBusReq : sl; saciRst : sl; req : sl; chip : slv(log2(SACI_NUM_CHIPS_G)-1 downto 0); @@ -75,6 +79,7 @@ architecture rtl of AxiLiteSaciMaster is constant REG_INIT_C : RegType := ( state => IDLE_S, + saciBusReq => '0', saciRst => '1', req => '0', chip => (others => '0'), @@ -163,34 +168,45 @@ begin -- Reset the timer v.saciRst := '0'; v.timer := 0; - -- Check for a write request - if (axilStatus.writeEnable = '1') then - -- SACI Commands - v.req := '1'; - v.op := '1'; - v.chip := axilWriteMaster.awaddr(22+CHIP_BITS_C-1 downto 22); - if (SACI_NUM_CHIPS_G = 1) then - v.chip := "0"; + v.saciBusReq := '0'; + if (saciBusGr = '1') then + -- Check for a write request + if (axilStatus.writeEnable = '1') then + v.saciBusReq := '1'; + -- SACI Commands + v.req := '1'; + v.op := '1'; + v.chip := axilWriteMaster.awaddr(22+CHIP_BITS_C-1 downto 22); + if (SACI_NUM_CHIPS_G = 1) then + v.chip := "0"; + end if; + v.cmd := axilWriteMaster.awaddr(20 downto 14); + v.addr := axilWriteMaster.awaddr(13 downto 2); + v.wrData := axilWriteMaster.wdata; + -- Next state + v.state := SACI_REQ_S; + -- Check for a read request + elsif (axilStatus.readEnable = '1') then + v.saciBusReq := '1'; + -- SACI Commands + v.req := '1'; + v.op := '0'; + v.chip := axilReadMaster.araddr(22+CHIP_BITS_C-1 downto 22); + if (SACI_NUM_CHIPS_G = 1) then + v.chip := "0"; + end if; + v.cmd := axilReadMaster.araddr(20 downto 14); + v.addr := axilReadMaster.araddr(13 downto 2); + v.wrData := (others => '0'); + -- Next state + v.state := SACI_REQ_S; end if; - v.cmd := axilWriteMaster.awaddr(20 downto 14); - v.addr := axilWriteMaster.awaddr(13 downto 2); - v.wrData := axilWriteMaster.wdata; - -- Next state - v.state := SACI_REQ_S; - -- Check for a read request - elsif (axilStatus.readEnable = '1') then - -- SACI Commands - v.req := '1'; - v.op := '0'; - v.chip := axilReadMaster.araddr(22+CHIP_BITS_C-1 downto 22); - if (SACI_NUM_CHIPS_G = 1) then - v.chip := "0"; + else + if (axilStatus.writeEnable = '1') then + axiSlaveWriteResponse(v.axilWriteSlave, AXI_RESP_SLVERR_C); + elsif (axilStatus.readEnable = '1') then + axiSlaveReadResponse(v.axilReadSlave, AXI_RESP_SLVERR_C); end if; - v.cmd := axilReadMaster.araddr(20 downto 14); - v.addr := axilReadMaster.araddr(13 downto 2); - v.wrData := (others => '0'); - -- Next state - v.state := SACI_REQ_S; end if; ---------------------------------------------------------------------- when SACI_REQ_S => @@ -240,6 +256,7 @@ begin -- Outputs axilReadSlave <= r.axilReadSlave; axilWriteSlave <= r.axilWriteSlave; + saciBusReq <= r.saciBusReq; end process comb; From 42705584c6717b92ab468b54d17321eefab82132 Mon Sep 17 00:00:00 2001 From: mkwiatko Date: Wed, 5 Dec 2018 23:09:45 -0800 Subject: [PATCH 09/92] optional bus arbitration handshake (bug fix) --- protocols/saci/rtl/AxiLiteSaciMaster.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/saci/rtl/AxiLiteSaciMaster.vhd b/protocols/saci/rtl/AxiLiteSaciMaster.vhd index 10a3ffdd63..f03f55e1c0 100644 --- a/protocols/saci/rtl/AxiLiteSaciMaster.vhd +++ b/protocols/saci/rtl/AxiLiteSaciMaster.vhd @@ -141,7 +141,7 @@ begin saciCmd => saciCmd, -- [out] saciRsp => saciRsp); -- [in] - comb : process (ack, axilReadMaster, axilRst, axilWriteMaster, fail, r, rdData) is + comb : process (ack, axilReadMaster, axilRst, axilWriteMaster, fail, r, rdData, saciBusGr) is variable v : RegType; variable axilStatus : AxiLiteStatusType; variable resp : slv(1 downto 0); From 98af6b68a7f1320a26d8ac9009201846e0b477cd Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 5 Mar 2019 14:51:52 -0800 Subject: [PATCH 10/92] Add rogue Device for AxiStreamScatterGather module --- python/surf/axi/_AxiStreamScatterGather.py | 84 ++++++++++++++++++++++ python/surf/axi/__init__.py | 1 + 2 files changed, 85 insertions(+) create mode 100644 python/surf/axi/_AxiStreamScatterGather.py diff --git a/python/surf/axi/_AxiStreamScatterGather.py b/python/surf/axi/_AxiStreamScatterGather.py new file mode 100644 index 0000000000..c3e2c2a739 --- /dev/null +++ b/python/surf/axi/_AxiStreamScatterGather.py @@ -0,0 +1,84 @@ +import pyrogue as pr + +class AxiStreamScatterGather(pr.Device): + def __init__(self, + description='Debug registers for AxiStreamScatterGather module', + **kwargs): + super().__init__(description=description, **kwargs) + + self.add(pr.RemoteVariable( + name = 'RxRamWrAddr', + mode = 'RO', + offset = 0x00, + disp = '{:08x}')) + + self.add(pr.RemoteVariable( + name = 'RxSofAddr', + mode = 'RO', + offset = 0x04, + disp = '{:08x}')) + + self.add(pr.RemoteVariable( + name = 'RxWordCount', + mode = 'RO', + offset = 0x08, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'RxFrameNumber', + mode = 'RO', + offset = 0x0C, + bitSize = 31 + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'RxError', + mode = 'RO', + offset = 0x0C, + bitSize = 1, + bitOffset = 31, + base = pr.Bool, + disp = '{:08x}')) + + self.add(pr.RemoteVariable( + name = 'TxRamRdAddr', + mode = 'RO', + offset = 0x10, + disp = '{:08x}')) + + self.add(pr.RemoteVariable( + name = 'TxWordCount', + mode = 'RO', + offset = 0x14, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'TxFrameNumber', + mode = 'RO', + offset = 0x18, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'LongWords', + mode = 'RO', + offset = 0x1C, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'LongWordCount', + mode = 'RO', + offset = 0x20, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'BadWords', + mode = 'RO', + offset = 0x24, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'BadWordCount', + mode = 'RO', + offset = 0x28, + disp = '{:d}')) + diff --git a/python/surf/axi/__init__.py b/python/surf/axi/__init__.py index ef86382067..a20580006c 100644 --- a/python/surf/axi/__init__.py +++ b/python/surf/axi/__init__.py @@ -15,3 +15,4 @@ from surf.axi._AxiVersion import * from surf.axi._AxiVersionLegacy import * from surf.axi._AxiStreamDmaV2 import * +from surf.axi._AxiStreamScatterGather import * From 588d6ffb5e4a17938c3e80e6bbf4b6342cb22b39 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 5 Mar 2019 16:10:53 -0800 Subject: [PATCH 11/92] Use TKEEP_FIXED_C for Pgp2b streams Also add new constant for 2-lane Pgp2b streams --- protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd index d52c7841e5..c313b83513 100755 --- a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd +++ b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd @@ -25,7 +25,8 @@ package Pgp2bPkg is ----------------------------------------------------- -- Constants ----------------------------------------------------- - constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_COMP_C); + constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_FIXED_C); + constant SSI_PGP2B_2LANE_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_FIXED_C); -- 8B10B Characters constant K_COM_C : slv(7 downto 0) := "10111100"; -- K28.5, 0xBC From 538838454c48ac279e947b3cb6991555a800f837 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 6 Mar 2019 09:32:03 -0800 Subject: [PATCH 12/92] Downgrade TKEEP_MODE = FIXED on master but not slave to a warning --- axi/axi-stream/rtl/AxiStreamFifoV2.vhd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamFifoV2.vhd b/axi/axi-stream/rtl/AxiStreamFifoV2.vhd index 41d1384199..e008f1627f 100644 --- a/axi/axi-stream/rtl/AxiStreamFifoV2.vhd +++ b/axi/axi-stream/rtl/AxiStreamFifoV2.vhd @@ -176,8 +176,9 @@ begin -- Cant use tkeep_fixed on master side when resizing or if not on slave side assert (not (MASTER_AXI_CONFIG_G.TKEEP_MODE_C = TKEEP_FIXED_C and SLAVE_AXI_CONFIG_G.TKEEP_MODE_C /= TKEEP_FIXED_C)) - report "AxiStreamFifoV2: Can't have TKEEP_MODE = TKEEP_FIXED on master side if not on slave side" - severity error; + report "AxiStreamFifoV2: TKEEP_MODE = TKEEP_FIXED on master side if not on slave side. "& + "This is dangerous as odd sized frames will be padded with garbage data." + severity warning; ------------------------- -- Slave Resize From 435ccb3f8519fb1e71a8dfb47cf6dcdb03effba5 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 6 Mar 2019 11:57:48 -0800 Subject: [PATCH 13/92] Fix typos --- python/surf/axi/_AxiStreamScatterGather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/surf/axi/_AxiStreamScatterGather.py b/python/surf/axi/_AxiStreamScatterGather.py index c3e2c2a739..2d4236d313 100644 --- a/python/surf/axi/_AxiStreamScatterGather.py +++ b/python/surf/axi/_AxiStreamScatterGather.py @@ -28,7 +28,7 @@ def __init__(self, name = 'RxFrameNumber', mode = 'RO', offset = 0x0C, - bitSize = 31 + bitSize = 31, disp = '{:d}')) self.add(pr.RemoteVariable( From f14ff2d5889d9a13a62a0707a9d44399dd2e88d0 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 6 Mar 2019 13:54:46 -0800 Subject: [PATCH 14/92] PGP2b TKEEP FIXED might have broken things. Reverting --- protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd index c313b83513..dd4c70ff15 100755 --- a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd +++ b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd @@ -25,8 +25,7 @@ package Pgp2bPkg is ----------------------------------------------------- -- Constants ----------------------------------------------------- - constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_FIXED_C); - constant SSI_PGP2B_2LANE_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_FIXED_C); + constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_COMP_C); -- 8B10B Characters constant K_COM_C : slv(7 downto 0) := "10111100"; -- K28.5, 0xBC From 2c0099c14e934288ec85297ef322b435ab48a04a Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:31:36 -0800 Subject: [PATCH 15/92] Make default sim version 2.0 --- protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLat.vhd | 2 +- protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLatWrapper.vhd | 2 +- protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7MultiLane.vhd | 2 +- protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7VarLat.vhd | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLat.vhd b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLat.vhd index ce2c49fd64..b3276fc500 100644 --- a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLat.vhd +++ b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLat.vhd @@ -33,7 +33,7 @@ entity Pgp2bGtp7FixedLat is ---------------------------------------------------------------------------------------------- -- Sim Generics -- SIM_GTRESET_SPEEDUP_G : string := "FALSE"; - SIM_VERSION_G : string := "1.0"; + SIM_VERSION_G : string := "2.0"; SIMULATION_G : boolean := false; STABLE_CLOCK_PERIOD_G : real := 4.0E-9; --units of seconds REF_CLK_FREQ_G : real := 125.0E6; diff --git a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLatWrapper.vhd b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLatWrapper.vhd index c61cba3920..f426f9f40c 100644 --- a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLatWrapper.vhd +++ b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7FixedLatWrapper.vhd @@ -31,7 +31,7 @@ entity Pgp2bGtp7FixedLatWrapper is TPD_G : time := 1 ns; COMMON_CLK_G : boolean := false;-- set true if (stableClk = axilClk) SIM_GTRESET_SPEEDUP_G : boolean := false; - SIM_VERSION_G : string := "1.0"; + SIM_VERSION_G : string := "2.0"; SIMULATION_G : boolean := false; -- PGP Settings VC_INTERLEAVE_G : integer := 0; -- No interleave Frames diff --git a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7MultiLane.vhd b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7MultiLane.vhd index 3c1df972a8..4201231d77 100644 --- a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7MultiLane.vhd +++ b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7MultiLane.vhd @@ -34,7 +34,7 @@ entity Pgp2bGtp7MultiLane is ---------------------------------------------------------------------------------------------- -- Sim Generics SIM_GTRESET_SPEEDUP_G : string := "FALSE"; - SIM_VERSION_G : string := "1.0"; + SIM_VERSION_G : string := "2.0"; STABLE_CLOCK_PERIOD_G : real := 4.0E-9; --units of seconds -- Configure PLL RXOUT_DIV_G : integer := 2; diff --git a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7VarLat.vhd b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7VarLat.vhd index 10321cb541..41702205e7 100644 --- a/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7VarLat.vhd +++ b/protocols/pgp/pgp2b/gtp7/rtl/Pgp2bGtp7VarLat.vhd @@ -30,7 +30,7 @@ entity Pgp2bGtp7VarLat is ---------------------------------------------------------------------------------------------- -- Sim Generics SIM_GTRESET_SPEEDUP_G : string := "FALSE"; - SIM_VERSION_G : string := "1.0"; + SIM_VERSION_G : string := "2.0"; STABLE_CLOCK_PERIOD_G : real := 4.0E-9; --units of seconds -- Configure PLL RXOUT_DIV_G : integer := 2; From 5da7fe81dd4c24bdfcbd0c2b0124e7d7daf9ccc7 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:32:36 -0800 Subject: [PATCH 16/92] Update allowable port range. Prep sideband for bidirectional operation. --- axi/simlink/sim/RogueSideBandWrap.vhd | 30 ++++++------ axi/simlink/sim/RogueTcpMemoryWrap.vhd | 68 +++++++++++++------------- axi/simlink/sim/RogueTcpStreamWrap.vhd | 10 ++-- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/axi/simlink/sim/RogueSideBandWrap.vhd b/axi/simlink/sim/RogueSideBandWrap.vhd index e7ed270657..7a8dbcce32 100755 --- a/axi/simlink/sim/RogueSideBandWrap.vhd +++ b/axi/simlink/sim/RogueSideBandWrap.vhd @@ -22,15 +22,17 @@ use work.AxiStreamPkg.all; entity RogueSideBandWrap is generic ( - TPD_G : time := 1 ns; - PORT_NUM_G : natural range 0 to 65535 := 1 - ); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 2000); port ( - sysClk : in sl; - sysRst : in sl; - opCode : out slv(7 downto 0); - opCodeEn : out sl; - remData : out slv(7 downto 0) + sysClk : in sl; + sysRst : in sl; + txOpCode : in slv(7 downto 0); + txOpCodeEn : in sl; + txRemData : in slv(7 downto 0); + rxOpCode : out slv(7 downto 0); + rxOpCodeEn : out sl; + rxRemData : out slv(7 downto 0) ); end RogueSideBandWrap; @@ -42,12 +44,12 @@ begin -- Sim Core U_RogueSideBand : entity work.RogueSideBand port map( - clock => sysClk, - reset => sysRst, - portNum => toSlv(PORT_NUM_G, 16), - opCode => opCode, - opCodeEn => opCodeEn, - remData => remData); + clock => sysClk, + reset => sysRst, + portNum => toSlv(PORT_NUM_G, 16), + opCode => opCode, + opCodeEn => opCodeEn, + remData => remData); end RogueSideBandWrap; diff --git a/axi/simlink/sim/RogueTcpMemoryWrap.vhd b/axi/simlink/sim/RogueTcpMemoryWrap.vhd index f9e6ea71b3..cb500c4ae3 100755 --- a/axi/simlink/sim/RogueTcpMemoryWrap.vhd +++ b/axi/simlink/sim/RogueTcpMemoryWrap.vhd @@ -13,27 +13,25 @@ -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- -LIBRARY ieee; -USE work.ALL; +library ieee; +use work.all; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.StdRtlPkg.all; use work.AxiLitePkg.all; -entity RogueTcpMemoryWrap is +entity RogueTcpMemoryWrap is generic ( - TPD_G : time := 1 ns; - PORT_NUM_G : natural range 0 to 65535 := 1 - ); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 9000); port ( - axilClk : in sl; - axilRst : in sl; - axilReadMaster : out AxiLiteReadMasterType; - axilReadSlave : in AxiLiteReadSlaveType; - axilWriteMaster : out AxiLiteWriteMasterType; - axilWriteSlave : in AxiLiteWriteSlaveType - ); + axilClk : in sl; + axilRst : in sl; + axilReadMaster : out AxiLiteReadMasterType; + axilReadSlave : in AxiLiteReadSlaveType; + axilWriteMaster : out AxiLiteWriteMasterType; + axilWriteSlave : in AxiLiteWriteSlaveType); end RogueTcpMemoryWrap; -- Define architecture @@ -44,28 +42,28 @@ begin -- Sim Core U_RogueTcpMemory : entity work.RogueTcpMemory port map ( - clock => axilClk, - reset => axilRst, - portNum => toSlv(PORT_NUM_G,16), - 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); + clock => axilClk, + reset => axilRst, + portNum => toSlv(PORT_NUM_G, 16), + 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; diff --git a/axi/simlink/sim/RogueTcpStreamWrap.vhd b/axi/simlink/sim/RogueTcpStreamWrap.vhd index a2efb2d51c..0259304b90 100644 --- a/axi/simlink/sim/RogueTcpStreamWrap.vhd +++ b/axi/simlink/sim/RogueTcpStreamWrap.vhd @@ -22,11 +22,11 @@ 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; - AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 9000; + SSI_EN_G : boolean := true; + CHAN_COUNT_G : positive range 1 to 256 := 1; + AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- Clock and Reset axisClk : in sl; From 38176a0e1741025480c1778283672cc33a38e39c Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:33:12 -0800 Subject: [PATCH 17/92] Use record names in init constants --- protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd | 93 +++++++++++------------ 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd index d52c7841e5..28858f4d72 100755 --- a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd +++ b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd @@ -57,10 +57,9 @@ package Pgp2bPkg is type Pgp2bRxInArray is array (natural range <>) of Pgp2bRxInType; constant PGP2B_RX_IN_INIT_C : Pgp2bRxInType := ( - '0', - '0', - "000" - ); + flush => '0', + resetRx => '0', + loopback => "000"); type Pgp2bRxOutType is record phyRxReady : sl; -- RX Phy is ready @@ -82,21 +81,20 @@ package Pgp2bPkg is type Pgp2bRxOutArray is array (natural range <>) of Pgp2bRxOutType; constant PGP2B_RX_OUT_INIT_C : Pgp2bRxOutType := ( - '0', - '0', - "00", - '0', - '0', - '0', - '0', - '0', - '0', - (others => '0'), - '0', - (others => '0'), - (others => '0'), - (others => '0') - ); + phyRxReady => '0', + linkReady => '0', + linkPolarity => "00", + frameRx => '0', + frameRxErr => '0', + cellError => '0', + linkDown => '0', + linkError => '0', + opCodeEn => '0', + opCode => (others => '0'), + remLinkReady => '0', + remLinkData => (others => '0'), + remOverflow => (others => '0'), + remPause => (others => '0')); ----------------------------------------------------- -- PGP2B TX non-data types @@ -115,24 +113,22 @@ package Pgp2bPkg is type Pgp2bTxInArray is array (natural range <>) of Pgp2bTxInType; constant PGP2B_TX_IN_INIT_C : Pgp2bTxInType := ( - '0', - '0', - (others => '0'), - (others => '0'), - '0', - '0', - '0' - ); + flush => '0', + opCodeEn => '0', + opCode => (others => '0'), + locData => (others => '0'), + flowCntlDis => '0', + resetTx => '0', + resetGt => '0'); constant PGP2B_TX_IN_HALF_DUPLEX_C : Pgp2bTxInType := ( - '0', - '0', - (others => '0'), - (others => '0'), - '1', - '0', - '0' - ); + flush => '0', + opCodeEn => '0', + opCode => (others => '0'), + locData => (others => '0'), + flowCntlDis => '1', + resetTx => '0', + resetGt => '0'); type Pgp2bTxOutType is record locOverflow : slv(3 downto 0); -- Local overflow status @@ -146,13 +142,12 @@ package Pgp2bPkg is type Pgp2bTxOutArray is array (natural range <>) of Pgp2bTxOutType; constant PGP2B_TX_OUT_INIT_C : Pgp2bTxOutType := ( - (others => '0'), - (others => '0'), - '0', - '0', - '0', - '0' - ); + locOverflow => (others => '0'), + locPause => (others => '0'), + phyTxReady => '0', + linkReady => '0', + frameTx => '0', + frameTxErr => '0'); ----------------------------------------------------- -- PGP2B RX Phy types @@ -176,11 +171,10 @@ package Pgp2bPkg is type Pgp2bRxPhyLaneInArray is array (natural range <>) of Pgp2bRxPhyLaneInType; constant PGP2B_RX_PHY_LANE_IN_INIT_C : Pgp2bRxPhyLaneInType := ( - (others => '0'), - (others => '0'), - (others => '0'), - (others => '0') - ); + data => (others => '0'), + dataK => (others => '0'), + dispErr => (others => '0'), + decErr => (others => '0')); ----------------------------------------------------- -- PGP2B TX Phy types @@ -194,9 +188,8 @@ package Pgp2bPkg is type Pgp2bTxPhyLaneOutArray is array (natural range <>) of Pgp2bTxPhyLaneOutType; constant PGP2B_TX_PHY_LANE_OUT_INIT_C : Pgp2bTxPhyLaneOutType := ( - (others => '0'), - (others => '0') - ); + data => (others => '0'), + datak => (others => '0')); end Pgp2bPkg; From 5e05009dddc1c4d49d8d17bcbb9007c92f60e5a3 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:34:04 -0800 Subject: [PATCH 18/92] Update allowable port range --- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index 91886ce56c..4c6cec43d0 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; - PORT_NUM_G : natural range 0 to 65535 := 1; - NUM_VC_G : integer range 1 to 16 := 4); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 1; + NUM_VC_G : integer range 1 to 16 := 4); port ( -- GT Ports pgpRefClk : in sl; @@ -93,11 +93,11 @@ begin GEN_VEC : for i in NUM_VC_G-1 downto 0 generate U_PGP_VC : entity work.RogueTcpStreamWrap generic map ( - TPD_G => TPD_G, - PORT_NUM_G => (PORT_NUM_G + i*2), - SSI_EN_G => true, - CHAN_COUNT_G => 1, - AXIS_CONFIG_G => PGP3_AXIS_CONFIG_C) + TPD_G => TPD_G, + PORT_NUM_G => (PORT_NUM_G + i*2), + SSI_EN_G => true, + CHAN_COUNT_G => 1, + AXIS_CONFIG_G => PGP3_AXIS_CONFIG_C) port map ( axisClk => clk, -- [in] axisRst => rst, -- [in] From 9291417f57caf1e123c20cd5344eca54fb7b3d12 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:34:53 -0800 Subject: [PATCH 19/92] Update allowable port range --- .../pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd | 46 ++++++++--------- .../pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd | 50 +++++++++---------- .../pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd | 48 +++++++++--------- 3 files changed, 72 insertions(+), 72 deletions(-) diff --git a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd index c2dcf5bcde..2380b407b1 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_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" + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 1024 to 49151 := 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" diff --git a/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd b/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd index 83a07311d7..f4825b7fc1 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_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 + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 1024 to 49151 := 9000; + 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" diff --git a/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd b/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd index 90a8b7208e..7841590433 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_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 + TPD_G : time := 1 ns; + ROGUE_SIM_EN_G : boolean := false; + ROGUE_SIM_PORT_NUM_G : natural range 1024 to 49151 := 9000; + 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" From dbf1d1dc478c50888f590583fec62560547e11bb Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 11:35:19 -0800 Subject: [PATCH 20/92] Add new PGP2b sim module --- protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd diff --git a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd new file mode 100644 index 0000000000..ff9e6dc156 --- /dev/null +++ b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------- +-- File : RoguePgp2bSim.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Wrapper on RogueStreamSim to simulate a PGPv3 +------------------------------------------------------------------------------- +-- 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; + +use work.StdRtlPkg.all; +use work.AxiLitePkg.all; +use work.AxiStreamPkg.all; +use work.Pgp3Pkg.all; + +library unisim; +use unisim.vcomponents.all; + +entity RoguePgp2bSim is + generic ( + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 9000; + NUM_VC_G : integer range 1 to 16 := 4; + EN_SIDEBAND_G : boolean := true); + port ( + -- PGP Clock and Reset + pgpClk : in sl; + pgpClkRst : in sl; + -- Non VC Rx Signals + pgpRxIn : in Pgp2bRxInType; + pgpRxOut : out Pgp2bRxOutType; + -- Non VC Tx Signals + pgpTxIn : in Pgp2bTxInType; + pgpTxOut : out Pgp2bTxOutType; + -- Frame Transmit Interface + pgpTxMasters : in AxiStreamMasterArray(NUM_VC_G-1 downto 0); + pgpTxSlaves : out AxiStreamSlaveArray(NUM_VC_G-1 downto 0); + -- Frame Receive Interface + pgpRxMasters : out AxiStreamMasterArray(NUM_VC_G-1 downto 0); + pgpRxSlaves : in AxiStreamSlaveArray(NUM_VC_G-1 downto 0); + -- AXI-Lite Register Interface (axilClk domain) + axilClk : in sl := '0'; -- Stable Clock + axilRst : in sl := '0'; + axilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + axilReadSlave : out AxiLiteReadSlaveType := AXI_LITE_READ_SLAVE_EMPTY_OK_C; + axilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + axilWriteSlave : out AxiLiteWriteSlaveType := AXI_LITE_WRITE_SLAVE_EMPTY_OK_C); +end entity RoguePgp2bSim; + +architecture sim of RoguePgp2bSim is + + signal txOut : Pgp2bTxOutType := PGP2B_TX_OUT_INIT_C; + signal rxOut : Pgp2bRxOutType := PGP2B_RX_OUT_INIT_C; + +begin + + pgpTxOut <= txOut; + pgpRxOut <= rxOut; + + GEN_VEC : for i in NUM_VC_G-1 downto 0 generate + U_PGP_VC : entity work.RogueTcpStreamWrap + generic map ( + TPD_G => TPD_G, + PORT_NUM_G => (PORT_NUM_G + i*2), + SSI_EN_G => true, + CHAN_COUNT_G => 1, + AXIS_CONFIG_G => SSI_PGP2B_CONFIG_C) + port map ( + axisClk => pgpClk, -- [in] + axisRst => pgpClkRst, -- [in] + sAxisMaster => pgpTxMasters(i), -- [in] + sAxisSlave => pgpTxSlaves(i), -- [out] + mAxisMaster => pgpRxMasters(i), -- [out] + mAxisSlave => pgpRxSlaves(i)); -- [in] + end generate GEN_VEC; + + GEN_SIDEBAND : if (EN_SIDEBAND_G) generate + U_RogueSideBandWrap_1 : entity work.RogueSideBandWrap + generic map ( + TPD_G => TPD_G, + PORT_NUM_G => PORT_NUM_G + 8) + port map ( + sysClk => sysClk, -- [in] + sysRst => sysRst, -- [in] + txOpCode => pgpTxIn.opCode, -- [in] + txOpCodeEn => pgpTxIn.opCodeEn, -- [in] + txRemData => pgpTxIn.locData, -- [in] + rxOpCode => rxOut.opCode, -- [out] + rxOpCodeEn => rxOut.opCodeEn, -- [out] + rxRemData => rxOut.remLinkData); -- [out] + end generate GEN_SIDEBAND; + + txOut.phyTxReady <= '1'; + txOut.linkReady <= '1'; + + rxOut.phyRxReady <= '1'; + rxOut.linkReady <= '1'; + rxOut.remRxLinkReady <= '1'; + +end sim; From 3bfc9e1a74e61b46629c832948b8fe101dcda15e Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 8 Mar 2019 16:13:24 -0800 Subject: [PATCH 21/92] Bug fixes --- axi/simlink/sim/RogueSideBandWrap.vhd | 8 ++++---- protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/axi/simlink/sim/RogueSideBandWrap.vhd b/axi/simlink/sim/RogueSideBandWrap.vhd index 7a8dbcce32..081e95a906 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 : natural range 1024 to 49151 := 2000); + PORT_NUM_G : natural range 1024 to 49151 := 9000); port ( sysClk : in sl; sysRst : in sl; @@ -47,9 +47,9 @@ begin clock => sysClk, reset => sysRst, portNum => toSlv(PORT_NUM_G, 16), - opCode => opCode, - opCodeEn => opCodeEn, - remData => remData); + opCode => rxOpCode, + opCodeEn => rxOpCodeEn, + remData => rxRemData); end RogueSideBandWrap; diff --git a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd index ff9e6dc156..a934f019fd 100644 --- a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd +++ b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd @@ -21,7 +21,7 @@ use ieee.std_logic_unsigned.all; use work.StdRtlPkg.all; use work.AxiLitePkg.all; use work.AxiStreamPkg.all; -use work.Pgp3Pkg.all; +use work.Pgp2bPkg.all; library unisim; use unisim.vcomponents.all; @@ -90,8 +90,8 @@ begin TPD_G => TPD_G, PORT_NUM_G => PORT_NUM_G + 8) port map ( - sysClk => sysClk, -- [in] - sysRst => sysRst, -- [in] + sysClk => pgpClk, -- [in] + sysRst => pgpClkRst, -- [in] txOpCode => pgpTxIn.opCode, -- [in] txOpCodeEn => pgpTxIn.opCodeEn, -- [in] txRemData => pgpTxIn.locData, -- [in] @@ -105,6 +105,6 @@ begin rxOut.phyRxReady <= '1'; rxOut.linkReady <= '1'; - rxOut.remRxLinkReady <= '1'; + rxOut.remLinkReady <= '1'; end sim; From 55a1db29aadd0c4beeff44f9678c9a550f1a5f81 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 11 Mar 2019 13:55:05 -0700 Subject: [PATCH 22/92] Make RogueSideBand bidirectional --- axi/simlink/src/RogueSideBand.c | 117 +++++++++++++++++++++++++------- axi/simlink/src/RogueSideBand.h | 25 +++++-- 2 files changed, 110 insertions(+), 32 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index 21d498bd2f..68e223536e 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -27,22 +27,57 @@ void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData) { char buffer[100]; + if ( data->zmqPush != NULL ) zmq_close(data->zmqPush ); if ( data->zmqPull != NULL ) zmq_close(data->zmqPull); if ( data->zmqCtx != NULL ) zmq_term(data->zmqCtx); data->zmqCtx = NULL; + data->zmqPush = NULL; data->zmqPull = NULL; data->zmqCtx = zmq_ctx_new(); - data->zmqPull = zmq_socket(data->zmqCtx,ZMQ_REP); + data->zmqPull = zmq_socket(data->zmqCtx,ZMQ_PULL); + data->zmqPush = zmq_socket(data->zmqCtx,ZMQ_PUSH); - vhpi_printf("RogueSideBand: Listening on port %i\n",data->port); + vhpi_printf("RogueSideBand: Listening on ports %i & %i\n",data->port, data->port+1); sprintf(buffer,"tcp://*:%i",data->port); if ( zmq_bind(data->zmqPull,buffer) ) { vhpi_assert("RogueSideBand: Failed to bind sideband port",vhpiFatal); return; } + + sprintf(buffer,"tcp://*:%i",data->port+1); + if ( zmq_bind(data->zmqPush,buffer) ) { + vhpi_assert("RogueTcpStream: Failed to bind push port",vhpiFatal); + return; + } + +} + +// Send a message +void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ) { + zmq_msg_t msg; + uint8_t data[4]; + + if ( (zmq_msg_init_size(&msg,4) < 0) ) { + vhpi_assert("RogueSideBand: Failed to init message",vhpiFatal); + return; + } + + data[0] = data->txOpCodeEn; + data[1] = data->txOpCode; + data[2] = data->txRemDataChanged; + data[3] = data->txRemData; + + memcpy(zmq_msg_data(&msg), data, 4); + + // Send data + if ( zmq_msg_send(data->zmqPush,&msg,ZMQ_DONTWAIT) < 0 ) { + vhpi_assert("RogueSideBand: Failed to send message",vhpiFatal); + } + + vhpi_printf("%lu RogueSideBand: Sent Opcode: %x\n", portData->simTime, data->txOpCode); } // Receive side data if it is available @@ -61,16 +96,16 @@ int RogueSideBandRecv ( RogueSideBandData *data, portDataT *portData ) { rd = zmq_msg_data(&rMsg); rsize = zmq_msg_size(&rMsg); - if ( rsize == 2 ) { + if ( rsize == 4 ) { - if ( rd[0] == 0xAA ) { - data->ocData = rd[1]; - data->ocDataEn = 1; - vhpi_printf("%lu RogueSideBand: Got opcode 0x%0.2x\n",portData->simTime,data->ocData); + if ( rd[0] == 0x01 ) { + data->rxOpCode = rd[1]; + data->rxOpCodeEn = 1; + vhpi_printf("%lu RogueSideBand: Got opcode 0x%0.2x\n",portData->simTime,data->rxOpCode); } - else if ( rd[0] == 0xBB ) { - data->remData = rd[1]; - vhpi_printf("%lu RogueSideBand: Got data 0x%0.2x\n",portData->simTime,data->remData); + if ( rd[2] == 0x01 ) { + data->rxRemData = rd[3]; + vhpi_printf("%lu RogueSideBand: Got data 0x%0.2x\n",portData->simTime,data->rxRemData); } // Ack @@ -98,18 +133,27 @@ void RogueSideBandInit(vhpiHandleT compInst) { portData->portDir[s_reset] = vhpiIn; portData->portDir[s_port] = vhpiIn; - portData->portDir[s_opCode] = vhpiOut; - portData->portDir[s_opCodeEn] = vhpiOut; - portData->portDir[s_remData] = vhpiOut; + portData->portDir[s_rxOpCode] = vhpiOut; + portData->portDir[s_rxOpCodeEn] = vhpiOut; + portData->portDir[s_rxRemData] = vhpiOut; + + portData->portDir[s_txOpCode] = vhpiIn; + portData->portDir[s_txOpCodeEn] = vhpiIn; + portData->portDir[s_txRemData] = vhpiIn; + // Set port widths portData->portWidth[s_clock] = 1; portData->portWidth[s_reset] = 1; portData->portWidth[s_port] = 16; - portData->portWidth[s_opCode] = 8; - portData->portWidth[s_opCodeEn] = 1; - portData->portWidth[s_remData] = 8; + portData->portWidth[s_rxOpCode] = 8; + portData->portWidth[s_rxOpCodeEn] = 1; + portData->portWidth[s_rxRemData] = 8; + + portData->portWidth[s_txOpCode] = 8; + portData->portWidth[s_txOpCodeEn] = 1; + portData->portWidth[s_txRemData] = 8; // Create data structure to hold state portData->stateData = data; @@ -130,6 +174,7 @@ void RogueSideBandUpdate ( void *userPtr ) { portDataT *portData = (portDataT*) userPtr; RogueSideBandData *data = (RogueSideBandData*)(portData->stateData); + send uint8_t = 0; // Detect clock edge if ( data->currClk != getInt(s_clock) ) { @@ -140,10 +185,14 @@ void RogueSideBandUpdate ( void *userPtr ) { // Reset is asserted if ( getInt(s_reset) == 1 ) { - data->remData = 0x00; - data->ocData = 0x00; - data->ocDataEn = 0; - setInt(s_opCodeEn,0); + data->rxRemData = 0x00; + data->rxOpCode = 0x00; + data->rxOpCodeEn = 0; + data->txRemData = 0x00; + data->txRemDataChanged = 0x00; + data->txOpCode = 0x00; + data->txOpCodeEn = 0; + setInt(s_rxOpCodeEn,0); } // Out of reset @@ -155,12 +204,30 @@ void RogueSideBandUpdate ( void *userPtr ) { RogueSideBandRestart(data,portData); } - // Sideband update + // TX OpCode + if (getInt(s_txOpCodeEn)) { + data->txOpCode = getInt(s_txOpCode); + data->txOpCodeEn = getInt(s_txOpCodeEn); + send = 1; + } + + //TX RemData + if (getInt(s_txRemData) != data->txRemData) { + data->txRemData = getInt(s_txRemData); + data->txRemDataChanged = 1; + send = 1; + } + + if (send) { + RogueSideBandSend(data, portData); + } + + // Rx Data RogueSideBandRecv(data,portData); - setInt(s_remData,data->remData); - setInt(s_opCode,data->ocData); - setInt(s_opCodeEn,data->ocDataEn); - data->ocDataEn = 0; // Only for one clock + setInt(s_rxRemData,data->rxRemData); + setInt(s_rxOpCode,data->rxOpCode); + setInt(s_rxOpCodeEn,data->rxOpCodeEn); + data->rxOpCodeEn = 0; // Only for one clock } } } diff --git a/axi/simlink/src/RogueSideBand.h b/axi/simlink/src/RogueSideBand.h index 20703f0975..ac17c15de0 100755 --- a/axi/simlink/src/RogueSideBand.h +++ b/axi/simlink/src/RogueSideBand.h @@ -20,11 +20,16 @@ #define s_reset 1 #define s_port 2 -#define s_opCode 3 -#define s_opCodeEn 4 -#define s_remData 5 +#define s_rxOpCode 3 +#define s_rxOpCodeEn 4 +#define s_rxRemData 5 -#define PORT_COUNT 6 +#define s_txOpCode 6 +#define s_txOpCodeEn 7 +#define s_txRemData 8 + + +#define PORT_COUNT 9 // Structure to track state typedef struct { @@ -32,12 +37,18 @@ typedef struct { uint32_t currClk; uint16_t port; - uint8_t remData; - uint8_t ocData; - uint8_t ocDataEn; + uint8_t rxRemData; + uint8_t rxOpCode; + uint8_t rxOpCodeEn; + + uint8_t txRemData; + uint8_t txRemDataChanged; + uint8_t txOpCode; + uint8_t txOpCodeEn; void * zmqCtx; void * zmqPull; + void * zmqPush; } RogueSideBandData; From b8000d7cc6a02a812744f7e3d440317d4ea604be Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 11 Mar 2019 14:13:16 -0700 Subject: [PATCH 23/92] Fix compile errors --- axi/simlink/src/RogueSideBand.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index 68e223536e..3f3ef9ce31 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -58,19 +58,19 @@ void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData) { // Send a message void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ) { zmq_msg_t msg; - uint8_t data[4]; + uint8_t ba[4]; if ( (zmq_msg_init_size(&msg,4) < 0) ) { vhpi_assert("RogueSideBand: Failed to init message",vhpiFatal); return; } - data[0] = data->txOpCodeEn; - data[1] = data->txOpCode; - data[2] = data->txRemDataChanged; - data[3] = data->txRemData; + ba[0] = data->txOpCodeEn; + ba[1] = data->txOpCode; + ba[2] = data->txRemDataChanged; + ba[3] = data->txRemData; - memcpy(zmq_msg_data(&msg), data, 4); + memcpy(zmq_msg_data(&msg), ba, 4); // Send data if ( zmq_msg_send(data->zmqPush,&msg,ZMQ_DONTWAIT) < 0 ) { @@ -174,7 +174,7 @@ void RogueSideBandUpdate ( void *userPtr ) { portDataT *portData = (portDataT*) userPtr; RogueSideBandData *data = (RogueSideBandData*)(portData->stateData); - send uint8_t = 0; + uint8_t send = 0; // Detect clock edge if ( data->currClk != getInt(s_clock) ) { From 3918f4ede63510ad3aae8a475873d62ce7abc6b5 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 12 Mar 2019 09:14:51 -0700 Subject: [PATCH 24/92] Add bidirectional operation --- axi/simlink/sim/RogueSideBand.vhd | 9 ++++++--- axi/simlink/sim/RogueSideBandWrap.vhd | 16 ++++++++++------ axi/simlink/src/RogueSideBand.c | 2 ++ axi/simlink/src/RogueSideBand.h | 5 +++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/axi/simlink/sim/RogueSideBand.vhd b/axi/simlink/sim/RogueSideBand.vhd index 7d6ba398b8..315fa329fc 100755 --- a/axi/simlink/sim/RogueSideBand.vhd +++ b/axi/simlink/sim/RogueSideBand.vhd @@ -24,9 +24,12 @@ entity RogueSideBand is port ( reset : in std_logic; portNum : in std_logic_vector(15 downto 0); - opCode : out std_logic_vector(7 downto 0); - opCodeEn : out std_logic; - remData : out std_logic_vector(7 downto 0) + txOpCode : in std_logic_vector(7 downto 0); + txOpCodeEn : in std_logic; + txRemData : in std_logic_vector(7 downto 0); + rxOpCode : out std_logic_vector(7 downto 0); + rxOpCodeEn : out std_logic; + rxRemData : out std_logic_vector(7 downto 0) ); end RogueSideBand; diff --git a/axi/simlink/sim/RogueSideBandWrap.vhd b/axi/simlink/sim/RogueSideBandWrap.vhd index 081e95a906..2733fc22a5 100755 --- a/axi/simlink/sim/RogueSideBandWrap.vhd +++ b/axi/simlink/sim/RogueSideBandWrap.vhd @@ -44,12 +44,16 @@ begin -- Sim Core U_RogueSideBand : entity work.RogueSideBand port map( - clock => sysClk, - reset => sysRst, - portNum => toSlv(PORT_NUM_G, 16), - opCode => rxOpCode, - opCodeEn => rxOpCodeEn, - remData => rxRemData); + clock => sysClk, + reset => sysRst, + portNum => toSlv(PORT_NUM_G, 16), + txOpCode => txOpCode, + txOpCodeEn => txOpCodeEn, + txRemData => txRemData, + rxOpCode => rxOpCode, + rxOpCodeEn => rxOpCodeEn, + rxRemData => rxRemData); + end RogueSideBandWrap; diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index 3f3ef9ce31..cb271b51ff 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -193,6 +193,8 @@ void RogueSideBandUpdate ( void *userPtr ) { data->txOpCode = 0x00; data->txOpCodeEn = 0; setInt(s_rxOpCodeEn,0); + setInt(s_rxOpCode, 0); + setInt(s_rxRemData, 0); } // Out of reset diff --git a/axi/simlink/src/RogueSideBand.h b/axi/simlink/src/RogueSideBand.h index ac17c15de0..b976d23c0c 100755 --- a/axi/simlink/src/RogueSideBand.h +++ b/axi/simlink/src/RogueSideBand.h @@ -61,8 +61,13 @@ void RogueSideBandUpdate ( void *userPtr ); // Restart the zmq link void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData); +// Send data +void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ); + // Receive data if it is available int RogueSideBandRecv ( RogueSideBandData *data, portDataT *portData ); + + #endif From 02df8b496de7df645e58a4d41715a61a1c2166aa Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 12 Mar 2019 22:37:03 -0700 Subject: [PATCH 25/92] Bug fixes --- axi/simlink/src/RogueSideBand.c | 25 ++++++++++++------------- axi/simlink/src/RogueSideBand.h | 13 ++++++------- axi/simlink/src/RogueTcpStream.c | 2 +- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index cb271b51ff..99a3b3c1aa 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -41,15 +41,15 @@ void RogueSideBandRestart(RogueSideBandData *data, portDataT *portData) { vhpi_printf("RogueSideBand: Listening on ports %i & %i\n",data->port, data->port+1); - sprintf(buffer,"tcp://*:%i",data->port); + sprintf(buffer,"tcp://*:%i",data->port+1); if ( zmq_bind(data->zmqPull,buffer) ) { vhpi_assert("RogueSideBand: Failed to bind sideband port",vhpiFatal); return; } - sprintf(buffer,"tcp://*:%i",data->port+1); + sprintf(buffer,"tcp://*:%i",data->port); if ( zmq_bind(data->zmqPush,buffer) ) { - vhpi_assert("RogueTcpStream: Failed to bind push port",vhpiFatal); + vhpi_assert("RogueSideBand: Failed to bind push port",vhpiFatal); return; } @@ -73,7 +73,7 @@ void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ) { memcpy(zmq_msg_data(&msg), ba, 4); // Send data - if ( zmq_msg_send(data->zmqPush,&msg,ZMQ_DONTWAIT) < 0 ) { + if ( zmq_msg_send(data->zmqPush,&msg,0) < 0 ) { vhpi_assert("RogueSideBand: Failed to send message",vhpiFatal); } @@ -111,7 +111,7 @@ int RogueSideBandRecv ( RogueSideBandData *data, portDataT *portData ) { // Ack zmq_msg_init_size(&tMsg,1); ((uint8_t *)zmq_msg_data(&tMsg))[0] = 0xFF; - zmq_msg_send(&tMsg,data->zmqPull,0); + zmq_msg_send(&tMsg,data->zmqPush,0); zmq_msg_close(&tMsg); } zmq_msg_close(&rMsg); @@ -133,28 +133,27 @@ void RogueSideBandInit(vhpiHandleT compInst) { portData->portDir[s_reset] = vhpiIn; portData->portDir[s_port] = vhpiIn; - portData->portDir[s_rxOpCode] = vhpiOut; - portData->portDir[s_rxOpCodeEn] = vhpiOut; - portData->portDir[s_rxRemData] = vhpiOut; - portData->portDir[s_txOpCode] = vhpiIn; portData->portDir[s_txOpCodeEn] = vhpiIn; portData->portDir[s_txRemData] = vhpiIn; + portData->portDir[s_rxOpCode] = vhpiOut; + portData->portDir[s_rxOpCodeEn] = vhpiOut; + portData->portDir[s_rxRemData] = vhpiOut; // Set port widths portData->portWidth[s_clock] = 1; portData->portWidth[s_reset] = 1; portData->portWidth[s_port] = 16; - portData->portWidth[s_rxOpCode] = 8; - portData->portWidth[s_rxOpCodeEn] = 1; - portData->portWidth[s_rxRemData] = 8; - portData->portWidth[s_txOpCode] = 8; portData->portWidth[s_txOpCodeEn] = 1; portData->portWidth[s_txRemData] = 8; + portData->portWidth[s_rxOpCode] = 8; + portData->portWidth[s_rxOpCodeEn] = 1; + portData->portWidth[s_rxRemData] = 8; + // Create data structure to hold state portData->stateData = data; diff --git a/axi/simlink/src/RogueSideBand.h b/axi/simlink/src/RogueSideBand.h index b976d23c0c..1df1779393 100755 --- a/axi/simlink/src/RogueSideBand.h +++ b/axi/simlink/src/RogueSideBand.h @@ -20,14 +20,13 @@ #define s_reset 1 #define s_port 2 -#define s_rxOpCode 3 -#define s_rxOpCodeEn 4 -#define s_rxRemData 5 - -#define s_txOpCode 6 -#define s_txOpCodeEn 7 -#define s_txRemData 8 +#define s_txOpCode 3 +#define s_txOpCodeEn 4 +#define s_txRemData 5 +#define s_rxOpCode 6 +#define s_rxOpCodeEn 7 +#define s_rxRemData 8 #define PORT_COUNT 9 diff --git a/axi/simlink/src/RogueTcpStream.c b/axi/simlink/src/RogueTcpStream.c index 8ce57aa80c..c246a7dcf5 100755 --- a/axi/simlink/src/RogueTcpStream.c +++ b/axi/simlink/src/RogueTcpStream.c @@ -28,7 +28,7 @@ void RogueTcpStreamRestart(RogueTcpStreamData *data, portDataT *portData) { char buffer[100]; if ( data->zmqPush != NULL ) zmq_close(data->zmqPush ); - if ( data->zmqPull != NULL ) zmq_close(data->zmqPush ); + if ( data->zmqPull != NULL ) zmq_close(data->zmqPull ); if ( data->zmqCtx != NULL ) zmq_term(data->zmqCtx); data->zmqCtx = NULL; From f03b9716513ab4913b5277b26a96be4d36bf3353 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 13 Mar 2019 15:48:11 -0700 Subject: [PATCH 26/92] Zero out any tdest value on inputs (as PGP does) --- protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd index a934f019fd..6352ced55b 100644 --- a/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd +++ b/protocols/pgp/pgp2b/core/tb/RoguePgp2bSim.vhd @@ -62,11 +62,24 @@ architecture sim of RoguePgp2bSim is signal txOut : Pgp2bTxOutType := PGP2B_TX_OUT_INIT_C; signal rxOut : Pgp2bRxOutType := PGP2B_RX_OUT_INIT_C; + signal pgpTxMastersLoc : AxiStreamMasterArray(NUM_VC_G-1 downto 0); + begin pgpTxOut <= txOut; pgpRxOut <= rxOut; + TDEST_ZERO : process (pgpTxMasters) is + variable tmp : AxiStreamMasterArray(NUM_VC_G-1 downto 0); + begin + tmp := pgpTxMasters; + for i in NUM_VC_G-1 downto 0 loop + tmp(i).tDest := (others => '0'); + end loop; + pgpTxMastersLoc <= tmp; + + end process TDEST_ZERO; + GEN_VEC : for i in NUM_VC_G-1 downto 0 generate U_PGP_VC : entity work.RogueTcpStreamWrap generic map ( @@ -76,12 +89,12 @@ begin CHAN_COUNT_G => 1, AXIS_CONFIG_G => SSI_PGP2B_CONFIG_C) port map ( - axisClk => pgpClk, -- [in] - axisRst => pgpClkRst, -- [in] - sAxisMaster => pgpTxMasters(i), -- [in] - sAxisSlave => pgpTxSlaves(i), -- [out] - mAxisMaster => pgpRxMasters(i), -- [out] - mAxisSlave => pgpRxSlaves(i)); -- [in] + axisClk => pgpClk, -- [in] + axisRst => pgpClkRst, -- [in] + sAxisMaster => pgpTxMastersLoc(i), -- [in] + sAxisSlave => pgpTxSlaves(i), -- [out] + mAxisMaster => pgpRxMasters(i), -- [out] + mAxisSlave => pgpRxSlaves(i)); -- [in] end generate GEN_VEC; GEN_SIDEBAND : if (EN_SIDEBAND_G) generate @@ -103,8 +116,8 @@ begin txOut.phyTxReady <= '1'; txOut.linkReady <= '1'; - rxOut.phyRxReady <= '1'; - rxOut.linkReady <= '1'; + rxOut.phyRxReady <= '1'; + rxOut.linkReady <= '1'; rxOut.remLinkReady <= '1'; end sim; From 1af6748f732e4f5ac817081a8490efe28ae847aa Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 13 Mar 2019 15:53:41 -0700 Subject: [PATCH 27/92] Fix parameter order bug, remove ack --- axi/simlink/src/RogueSideBand.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index 99a3b3c1aa..aa07e72527 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -73,7 +73,7 @@ void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ) { memcpy(zmq_msg_data(&msg), ba, 4); // Send data - if ( zmq_msg_send(data->zmqPush,&msg,0) < 0 ) { + if ( zmq_msg_send(&msg,data->zmqPush,ZMQ_DONTWAIT) < 0 ) { vhpi_assert("RogueSideBand: Failed to send message",vhpiFatal); } @@ -85,7 +85,6 @@ int RogueSideBandRecv ( RogueSideBandData *data, portDataT *portData ) { uint8_t * rd; uint32_t rsize; zmq_msg_t rMsg; - zmq_msg_t tMsg; zmq_msg_init(&rMsg); if ( zmq_msg_recv(&rMsg,data->zmqPull,ZMQ_DONTWAIT) <= 0 ) { @@ -108,11 +107,6 @@ int RogueSideBandRecv ( RogueSideBandData *data, portDataT *portData ) { vhpi_printf("%lu RogueSideBand: Got data 0x%0.2x\n",portData->simTime,data->rxRemData); } - // Ack - zmq_msg_init_size(&tMsg,1); - ((uint8_t *)zmq_msg_data(&tMsg))[0] = 0xFF; - zmq_msg_send(&tMsg,data->zmqPush,0); - zmq_msg_close(&tMsg); } zmq_msg_close(&rMsg); return(rsize); From f5655aec2095d24205431d361951bb106e74b785 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Wed, 13 Mar 2019 15:53:53 -0700 Subject: [PATCH 28/92] Add debugging --- axi/simlink/src/RogueTcpStream.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/axi/simlink/src/RogueTcpStream.c b/axi/simlink/src/RogueTcpStream.c index c246a7dcf5..3070ee4e47 100755 --- a/axi/simlink/src/RogueTcpStream.c +++ b/axi/simlink/src/RogueTcpStream.c @@ -94,8 +94,10 @@ void RogueTcpStreamSend ( RogueTcpStreamData *data, portDataT *portData ) { // Send data for (x=0; x < 4; x++) { - if ( zmq_sendmsg(data->zmqPush,&(msg[x]),(x==3)?0:ZMQ_SNDMORE) < 0 ) - vhpi_assert("RogueTcpStream: Failed to send message",vhpiFatal); + if ( zmq_sendmsg(data->zmqPush,&(msg[x]),(x==3)?0:ZMQ_SNDMORE) < 0 ) { + vhpi_printf("Failed to send message on port %i\n", data->port+1); + vhpi_assert("RogueTcpStream: Failed to send message",vhpiFatal); + } } data->ibSize = 0; From b447e553e83ef76f7be80b1af3f4b2a7238dc961 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 18 Mar 2019 11:24:27 -0700 Subject: [PATCH 29/92] Better debug messages --- axi/simlink/src/RogueSideBand.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/axi/simlink/src/RogueSideBand.c b/axi/simlink/src/RogueSideBand.c index aa07e72527..93119f7245 100755 --- a/axi/simlink/src/RogueSideBand.c +++ b/axi/simlink/src/RogueSideBand.c @@ -76,8 +76,12 @@ void RogueSideBandSend ( RogueSideBandData *data, portDataT *portData ) { if ( zmq_msg_send(&msg,data->zmqPush,ZMQ_DONTWAIT) < 0 ) { vhpi_assert("RogueSideBand: Failed to send message",vhpiFatal); } - - vhpi_printf("%lu RogueSideBand: Sent Opcode: %x\n", portData->simTime, data->txOpCode); + if (data->txOpCodeEn) { + vhpi_printf("%lu RogueSideBand: Sent Opcode: %x\n", portData->simTime, data->txOpCode); + } + if (data->txRemDataChanged) { + vhpi_printf("%lu RogueSideBand: Sent remData: %x\n", portData->simTime, data->txRemData); + } } // Receive side data if it is available From 71a3f05702fbaf74a5062de52f5306afac5aeae4 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 18 Mar 2019 11:25:16 -0700 Subject: [PATCH 30/92] Fix bug where tuserfirst gets lost when frame size is 1 transaction --- axi/simlink/src/RogueTcpStream.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/axi/simlink/src/RogueTcpStream.c b/axi/simlink/src/RogueTcpStream.c index 3070ee4e47..c67dd1db77 100755 --- a/axi/simlink/src/RogueTcpStream.c +++ b/axi/simlink/src/RogueTcpStream.c @@ -22,6 +22,7 @@ #include #include #include +#include // Start/resetart zeromq server void RogueTcpStreamRestart(RogueTcpStreamData *data, portDataT *portData) { @@ -62,6 +63,7 @@ void RogueTcpStreamSend ( RogueTcpStreamData *data, portDataT *portData ) { uint8_t chan; uint8_t err; uint32_t x; + int error; if ( (zmq_msg_init_size(&(msg[0]),2) < 0) || // Flags (zmq_msg_init_size(&(msg[1]),1) < 0) || // Channel @@ -94,14 +96,15 @@ void RogueTcpStreamSend ( RogueTcpStreamData *data, portDataT *portData ) { // Send data for (x=0; x < 4; x++) { - if ( zmq_sendmsg(data->zmqPush,&(msg[x]),(x==3)?0:ZMQ_SNDMORE) < 0 ) { - vhpi_printf("Failed to send message on port %i\n", data->port+1); - vhpi_assert("RogueTcpStream: Failed to send message",vhpiFatal); + if ( zmq_msg_send(&(msg[x]), data->zmqPush, (x==3)?0:ZMQ_SNDMORE) < 0 ) { + error = errno; + vhpi_printf("Failed to send message on port %i - x: %i - err: %i\n", data->port+1, x, error); + vhpi_printf("Error: %s\n", strerror(error)); + vhpi_assert("RogueTcpStream: Failed to send message",vhpiFatal); } } - + vhpi_printf("%lu RogueTcpStream: Send data: Size: %i, flags: %x, chan: %x, err: %x, port: %i\n", portData->simTime, data->ibSize, flags, chan, err, data->port+1); data->ibSize = 0; - vhpi_printf("%lu RogueTcpStream: Send data: Size: %i\n", portData->simTime, data->ibSize); } @@ -166,7 +169,7 @@ int RogueTcpStreamRecv ( RogueTcpStreamData *data, portDataT *portData ) { if ( err ) data->obLuser |= 0x01; } - vhpi_printf("%lu RogueTcpStream: Recv data: Size: %i\n", portData->simTime, data->obSize); + vhpi_printf("%lu RogueTcpStream: Recv data: Size: %i, flags: %x, chan: %i, err: %i, port: %i\n", portData->simTime, data->obSize, flags, chan, err, data->port); } else size = 0; @@ -348,8 +351,14 @@ void RogueTcpStreamUpdate ( void *userPtr ) { for (x=0; x< 8; x++) { if ( x < 4 ) { dLow |= (data->obData[data->obCount] << (x*8)); - if ( (data->obCount+1) == data->obSize ) + if ( (data->obCount+1) == data->obSize ) { + if (data->obCount < 4) { + setInt(s_obUserLow,(data->obLuser << (x*8))|(data->obFuser)); + } + else { setInt(s_obUserLow,(data->obLuser << (x*8))); + } + } } else { dHigh |= (data->obData[data->obCount] << ((x-4)*8)); From 4491ac2b8af88464eb4269e8c5ca0cd795d43696 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 11:47:23 -0700 Subject: [PATCH 31/92] updating RoguePgp3Sim.vhd w/ sideband --- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 23 ++++++++++++++++--- .../pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd | 3 +-- .../pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd | 2 +- .../pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index 4c6cec43d0..da13e62062 100644 --- a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd +++ b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd @@ -28,9 +28,10 @@ use unisim.vcomponents.all; entity RoguePgp3Sim is generic ( - TPD_G : time := 1 ns; - PORT_NUM_G : natural range 1024 to 49151 := 1; - NUM_VC_G : integer range 1 to 16 := 4); + TPD_G : time := 1 ns; + PORT_NUM_G : natural range 1024 to 49151 := 1; + NUM_VC_G : integer range 1 to 16 := 4; + EN_SIDEBAND_G : boolean := true); port ( -- GT Ports pgpRefClk : in sl; @@ -106,6 +107,22 @@ begin mAxisMaster => pgpRxMasters(i), -- [out] mAxisSlave => pgpRxSlaves(i)); -- [in] end generate GEN_VEC; + + GEN_SIDEBAND : if (EN_SIDEBAND_G) generate + U_RogueSideBandWrap_1 : entity work.RogueSideBandWrap + generic map ( + TPD_G => TPD_G, + PORT_NUM_G => PORT_NUM_G + 32) + port map ( + sysClk => pgpClk, + sysRst => pgpClkRst, + txOpCode => pgpTxIn.opCodeData(7 downto 0), + txOpCodeEn => pgpTxIn.opCodeEn, + txRemData => pgpTxIn.opCodeData(15 downto 8), + rxOpCode => rxOut.opCodeData(7 downto 0), + rxOpCodeEn => rxOut.opCodeEn, + rxRemData => rxOut.opCodeData(15 downto 8)); + end generate GEN_SIDEBAND; txOut.phyTxActive <= '1'; txOut.linkReady <= '1'; diff --git a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd index 2380b407b1..8dac7e448e 100644 --- a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd +++ b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd @@ -18,7 +18,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - use work.StdRtlPkg.all; use work.AxiStreamPkg.all; use work.AxiLitePkg.all; @@ -268,7 +267,7 @@ begin U_Rogue : entity work.RoguePgp3Sim generic map( TPD_G => TPD_G, - PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*34)), NUM_VC_G => NUM_VC_G) port map( -- GT Ports diff --git a/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd b/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd index f4825b7fc1..6056a67ef5 100644 --- a/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd +++ b/protocols/pgp/pgp3/gtp7/rtl/Pgp3Gtp7Wrapper.vhd @@ -393,7 +393,7 @@ begin U_Rogue : entity work.RoguePgp3Sim generic map( TPD_G => TPD_G, - PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*34)), NUM_VC_G => NUM_VC_G) port map( -- GT Ports diff --git a/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd b/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd index 7841590433..a488f17724 100644 --- a/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd +++ b/protocols/pgp/pgp3/gtx7/rtl/Pgp3Gtx7Wrapper.vhd @@ -324,7 +324,7 @@ begin U_Rogue : entity work.RoguePgp3Sim generic map( TPD_G => TPD_G, - PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*32)), + PORT_NUM_G => (ROGUE_SIM_PORT_NUM_G+(i*34)), NUM_VC_G => NUM_VC_G) port map( -- GT Ports From b54c7549f33f99631dc865cf446dc63cc853e0d9 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 12:17:16 -0700 Subject: [PATCH 32/92] bug fix --- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 2 +- protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index da13e62062..f18fe7cd49 100644 --- a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd +++ b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd @@ -29,7 +29,7 @@ use unisim.vcomponents.all; entity RoguePgp3Sim is generic ( TPD_G : time := 1 ns; - PORT_NUM_G : natural range 1024 to 49151 := 1; + PORT_NUM_G : natural range 1024 to 49151 := 9000; NUM_VC_G : integer range 1 to 16 := 4; EN_SIDEBAND_G : boolean := true); port ( diff --git a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd index 8dac7e448e..591a6dcf8b 100644 --- a/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd +++ b/protocols/pgp/pgp3/gthUs/rtl/Pgp3GthUsWrapper.vhd @@ -30,7 +30,7 @@ entity Pgp3GthUsWrapper is generic ( TPD_G : time := 1 ns; ROGUE_SIM_EN_G : boolean := false; - ROGUE_SIM_PORT_NUM_G : natural range 1024 to 49151 := 1; + ROGUE_SIM_PORT_NUM_G : natural range 1024 to 49151 := 9000; 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 From 0052f706aa3525dff41c6672431a9af003e643c5 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 12:20:29 -0700 Subject: [PATCH 33/92] bug fix --- axi/axi-lite/rtl/AxiDualPortRam.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axi/axi-lite/rtl/AxiDualPortRam.vhd b/axi/axi-lite/rtl/AxiDualPortRam.vhd index c6f1bbbbee..3010bdc4ac 100644 --- a/axi/axi-lite/rtl/AxiDualPortRam.vhd +++ b/axi/axi-lite/rtl/AxiDualPortRam.vhd @@ -85,7 +85,7 @@ architecture rtl of AxiDualPortRam is axiReadSlave : AxiLiteReadSlaveType; axiAddr : slv(ADDR_WIDTH_G-1 downto 0); axiWrStrobe : slv(ADDR_AXI_WORDS_C*4-1 downto 0); - rdLatecy : natural range 0 to 3; + rdLatecy : natural range 0 to 4; state : StateType; end record; From f6165545c2d353222943a02e6c5feef8de5deea2 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 12:21:44 -0700 Subject: [PATCH 34/92] bug fix --- protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd index f18fe7cd49..2c65b763a3 100644 --- a/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd +++ b/protocols/pgp/pgp3/core/tb/RoguePgp3Sim.vhd @@ -114,8 +114,8 @@ begin TPD_G => TPD_G, PORT_NUM_G => PORT_NUM_G + 32) port map ( - sysClk => pgpClk, - sysRst => pgpClkRst, + sysClk => clk, + sysRst => rst, txOpCode => pgpTxIn.opCodeData(7 downto 0), txOpCodeEn => pgpTxIn.opCodeEn, txRemData => pgpTxIn.opCodeData(15 downto 8), From 755a482d98d909cd210eb8d2aad1b23d6b3957a8 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 14:29:03 -0700 Subject: [PATCH 35/92] adding bypass reg to AxiStreamBatcherEventBuilder --- .../rtl/AxiStreamBatcherEventBuilder.vhd | 35 +++++++++++-------- .../surf/axi/_AxiStreamBatcherEventBuilder.py | 8 +++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd index 9674d46c7d..7a6ae36e28 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd @@ -78,6 +78,7 @@ architecture rtl of AxiStreamBatcherEventBuilder is maxSubFrames : slv(15 downto 0); timer : slv(31 downto 0); timeout : slv(31 downto 0); + bypass : slv(NUM_SLAVES_G-1 downto 0); dataCnt : Slv32Array(NUM_SLAVES_G-1 downto 0); nullCnt : Slv32Array(NUM_SLAVES_G-1 downto 0); timeoutDropCnt : Slv32Array(NUM_SLAVES_G-1 downto 0); @@ -102,6 +103,7 @@ architecture rtl of AxiStreamBatcherEventBuilder is maxSubFrames => toSlv(NUM_SLAVES_G, 16), timer => (others => '0'), timeout => (others => '0'), + bypass => (others => '0'), dataCnt => (others => (others => '0')), nullCnt => (others => (others => '0')), timeoutDropCnt => (others => (others => '0')), @@ -214,16 +216,16 @@ begin if (r.hardRst = '1') or (r.softRst = '1') then -- Reset the register v := REG_INIT_C; - + -- -- Check for soft reset (unclear if we want to support a hard reset that also resets the registers. it might confuse 'novice' users who randomly hitting different resets) -- if (r.softRst = '1') then - - -- Preserve the resister configurations - v.timeout := r.timeout; - v.blowoff := r.blowoff; - + + -- Preserve the resister configurations + v.timeout := r.timeout; + v.blowoff := r.blowoff; + -- end if; - + end if; -- Determine the transaction type @@ -235,6 +237,7 @@ begin axiSlaveRegisterR(axilEp, toSlv(4*i + 256, 12), 0, r.nullCnt(i)); axiSlaveRegisterR(axilEp, toSlv(4*i + 512, 12), 0, r.timeoutDropCnt(i)); end loop; + axiSlaveRegister (axilEp, x"FD0", 0, v.bypass); axiSlaveRegister (axilEp, x"FF0", 0, v.timeout); axiSlaveRegisterR(axilEp, x"FF4", 0, toSlv(NUM_SLAVES_G, 8)); axiSlaveRegisterR(axilEp, x"FF4", 8, dbg); @@ -252,10 +255,14 @@ begin -- Reset the timer v.timer := (others => '0'); end if; + if (r.bypass /= v.bypass) or (r.blowoff /= v.blowoff) then + -- Perform a soft-reset + v.softRst := '1'; + end if; -- Reset the flow control strobes for i in (NUM_SLAVES_G-1) downto 0 loop - v.rxSlaves(i).tReady := '0'; + v.rxSlaves(i).tReady := r.bypass(i); end loop; if (txSlave.tReady = '1') then v.txMaster.tValid := '0'; @@ -271,8 +278,8 @@ begin -- Loop through RX channels for i in (NUM_SLAVES_G-1) downto 0 loop - -- Check if no data - if (rxMasters(i).tValid = '0') then + -- Check if no data and not bypassing + if (rxMasters(i).tValid = '0') and (r.bypass(i) = '0') then -- Reset the flags v.ready := '0'; v.accept(i) := '0'; @@ -290,10 +297,10 @@ begin (getTKeep(rxMasters(i).tKeep(AXIS_CONFIG_G.TDATA_BYTES_C-1 downto 0), AXIS_CONFIG_G) = 1) then -- byte count = 1 -- NULL frame detected v.accept(i) := '0'; - v.nullDet(i) := '1'; + v.nullDet(i) := not(r.bypass(i)); else -- Normal frame detected - v.accept(i) := '1'; + v.accept(i) := not(r.bypass(i)); v.nullDet(i) := '0'; end if; end if; @@ -370,8 +377,8 @@ begin end if; ---------------------------------------------------------------------- when MOVE_S => - -- Check for timeout channel - if (r.timeoutDet(r.index) = '1') then + -- Check for timeout or bypass on the channel + if (r.timeoutDet(r.index) = '1') or (r.bypass(r.index) = '1') then -- Check for last channel if (r.index = NUM_SLAVES_G-1) then diff --git a/python/surf/axi/_AxiStreamBatcherEventBuilder.py b/python/surf/axi/_AxiStreamBatcherEventBuilder.py index 4a3a253067..49a34f9974 100644 --- a/python/surf/axi/_AxiStreamBatcherEventBuilder.py +++ b/python/surf/axi/_AxiStreamBatcherEventBuilder.py @@ -61,6 +61,14 @@ def __init__(self, pollInterval = 1, ) + self.add(pr.RemoteVariable( + name = 'Bypass', + description = 'Mask to bypass a channel', + offset = 0xFD0, + bitSize = numberSlaves, + mode = 'RW', + )) + self.add(pr.RemoteVariable( name = 'Timeout', description = 'Sets the timer\'s timeout duration. Setting to 0x0 (default) bypasses the timeout feature', From 4e4276592bf6a7780a852a28ef062218a67fd418 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 16:31:59 -0700 Subject: [PATCH 36/92] adding _UartPiranha4.py --- python/surf/protocols/clink/_UartPiranha4.py | 385 +++++++++++++++++++ python/surf/protocols/clink/__init__.py | 7 +- 2 files changed, 389 insertions(+), 3 deletions(-) create mode 100644 python/surf/protocols/clink/_UartPiranha4.py diff --git a/python/surf/protocols/clink/_UartPiranha4.py b/python/surf/protocols/clink/_UartPiranha4.py new file mode 100644 index 0000000000..e1063aa72a --- /dev/null +++ b/python/surf/protocols/clink/_UartPiranha4.py @@ -0,0 +1,385 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# Title : PyRogue CameraLink module +#----------------------------------------------------------------------------- +# File : _UartPiranha4.py +# Created : 2017-11-21 +#----------------------------------------------------------------------------- +# Description: +# PyRogue CameraLink module +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +import surf.protocols.clink as clink + +class UartPiranha4(pr.Device): + def __init__( self, + name = 'UartPiranha4', + description = 'Uart Opal000 channel access', + serial = None, + **kwargs): + super().__init__(name=name, description=description, **kwargs) + + if serial is not None: + + # Attach the serial devices + self._rx = clink.ClinkSerialRx() + pr.streamConnect(serial,self._rx) + + self._tx = clink.ClinkSerialTx() + pr.streamConnect(self._tx,serial) + + ############################## + # Variables + ############################## + + self.add(pr.LocalVariable( + name = 'CCF', + description = 'Calibrate user FPN dark flat field coefficients', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ccf {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CLS', + description = 'Camera Link clock frequency', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cls {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CLM', + description = 'Camera Link Mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'clm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[0]', + description = 'Calibrate user PRNU flat field coefficients: Algorithm Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[1]', + description = 'Calibrate user PRNU flat field coefficients: \# of lines to average Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[2]', + description = 'Calibrate user PRNU flat field coefficients: Target Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'DST', + description = 'Use this command to switch between Area and Single Line modes.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'dst {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'FFM', + description = 'Set flat field mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ffm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'FRS', + description = 'Set scan direction controlled reverse set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'GCP', + description = 'Display current value of camera configuration parameters', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('gcp') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'GET', + description = 'The /"get/" command displays the current value(s) of the feature specified in the string parameter. Note that the parameter is preceded by a single quote \"\". Using this command will be easier for control software than parsing the output from the \"gcp\" command.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'get {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'H', + description = 'Display list of three letter commands', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('h') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'LPC', + description = 'Load user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'lpc {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'RC', + description = 'Resets the camera to the saved user default settings. These settings are saved using the usd command.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('rc') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'ROI', + description = 'Flat field region of interest', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'ROI[0]', + description = 'Flat field region of interest: First pixel Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'ROI[1]', + description = 'Flat field region of interest: Last pixel Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'RPC', + description = 'Reset all user FPN values to zero and all user PRNU coefficients to one', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('rpc') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SAC', + description = 'Set AOI Counter', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sac {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[0]', + description = 'Define an AOI: Selector Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[1]', + description = 'Define an AOI: Offset Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[2]', + description = 'Define an AOI: Width Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAM', + description = 'Set AOI mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sam {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SBH', + description = 'Set horizontal binning', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sbh {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SBR', + description = 'Set baud rate', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sbr {value}') if value!='' else '' + units = 'bps', + )) + + self.add(pr.LocalVariable( + name = 'SBV', + description = 'Set vertical binning', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sbv {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SCD', + description = 'Set sensor scan direction', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'scd {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SEM', + description = 'Set exposure time mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sem {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SET', + description = 'Set internal exposure time in nanoseconds – 25 ns resolution', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'set {value}') if value!='' else '' + units = '25ns', + )) + + self.add(pr.LocalVariable( + name = 'SMM', + description = 'Set mirroring mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'smm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SPF', + description = 'Set pixel format', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'spf {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SSB', + description = 'Set contrast offset – single value added to all pixels after PRNU/flat field coefficients (before gain).', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ssb {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SSF', + description = 'Set internal line rate in Hz', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ssf {value}') if value!='' else '' + units = 'Hz', + )) + + self.add(pr.LocalVariable( + name = 'SSG', + description = 'Set gain as a single value multiplied by all pixels.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ssg {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'STG', + description = 'Set TDI Stages', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'stg {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'STM', + description = 'Set trigger mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'stm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SVM', + description = 'Select test pattern', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'svm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USD', + description = 'Select user set to load when camera is reset', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'usd {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USL', + description = 'Load user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'usl {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USS', + description = 'Save user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'uss {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'VT', + description = 'Display internal temperature in degrees Celsius', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('vt') if value!='' else '' + units = 'degC', + )) + + self.add(pr.LocalVariable( + name = 'VV', + description = 'Display supply voltage', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString('vv') if value!='' else '' + units = 'V', + )) + \ No newline at end of file diff --git a/python/surf/protocols/clink/__init__.py b/python/surf/protocols/clink/__init__.py index 298ed62fb7..b365473ec1 100644 --- a/python/surf/protocols/clink/__init__.py +++ b/python/surf/protocols/clink/__init__.py @@ -9,10 +9,11 @@ ## the terms contained in the LICENSE.txt file. ############################################################################## -from surf.protocols.clink._ClinkTop import * +from surf.protocols.clink._ClinkTop import * from surf.protocols.clink._ClinkSerialRx import * from surf.protocols.clink._ClinkSerialTx import * -from surf.protocols.clink._ClinkChannel import * +from surf.protocols.clink._ClinkChannel import * # Library of support Camera UART interfaces -from surf.protocols.clink._UartOpal000 import * +from surf.protocols.clink._UartOpal000 import * +from surf.protocols.clink._UartPiranha4 import * From 6b1e0a87eff07e9ae6fd55f22f03a991ea08eeba Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 16:32:32 -0700 Subject: [PATCH 37/92] removing since already include in ClinkSerialTx at line42 --- python/surf/protocols/clink/_UartOpal000.py | 56 +++++++++------------ 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/python/surf/protocols/clink/_UartOpal000.py b/python/surf/protocols/clink/_UartOpal000.py index 33c7d4d276..d6729477f5 100644 --- a/python/surf/protocols/clink/_UartOpal000.py +++ b/python/surf/protocols/clink/_UartOpal000.py @@ -20,12 +20,6 @@ import pyrogue as pr import surf.protocols.clink as clink - -import time - -class UartOpal000Tx(clink.ClinkSerialTx): - def __init__(self,**kwargs): - super().__init__(**kwargs) class UartOpal000Rx(clink.ClinkSerialRx): def __init__(self,**kwargs): @@ -47,7 +41,7 @@ def _acceptFrame(self,frame): elif ba[i] == 0x25: print("Got NAK Response: {}".format(''.join(self._cur))) self._cur = [] - elif c != '\r': + elif c != '': self._cur.append(c) class UartOpal000(pr.Device): @@ -64,7 +58,7 @@ def __init__( self, self._rx = UartOpal000Rx() pr.streamConnect(serial,self._rx) - self._tx = UartOpal000Tx() + self._tx = clink.ClinkSerialTx() pr.streamConnect(self._tx,serial) ############################## @@ -76,7 +70,7 @@ def __init__( self, description = 'Selects the exposure control source and event selection', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}\r') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -84,7 +78,7 @@ def __init__( self, description = 'Selects the exposure control source and event selection', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}\r') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -92,7 +86,7 @@ def __init__( self, description = 'Selects the frame start control source and event selection', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}\r') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -100,7 +94,7 @@ def __init__( self, description = 'Selects the frame start control source and event selection', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}\r') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -108,7 +102,7 @@ def __init__( self, description = 'Enables or disables the defect pixel correction.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@DPE{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@DPE{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -116,7 +110,7 @@ def __init__( self, description = 'Sets the frame period.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@FP{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@FP{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -124,7 +118,7 @@ def __init__( self, description = 'Selects the FSTROBE output and polarity', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@FSM{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@FSM{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -132,7 +126,7 @@ def __init__( self, description = 'Configures the FSTROBE, step, delay and active', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}\r') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -140,7 +134,7 @@ def __init__( self, description = 'Configures the FSTROBE, step, delay and active', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}\r') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' )) self.add(pr.LocalVariable( @@ -148,7 +142,7 @@ def __init__( self, description = 'Sets the digital gain of the camera.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@GA{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@GA{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -156,7 +150,7 @@ def __init__( self, description = 'Sets the integration time.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@IT{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@IT{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -164,7 +158,7 @@ def __init__( self, description = 'Enables or disables the mirror function.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@MI{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@MI{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -172,7 +166,7 @@ def __init__( self, description = 'Sets the operating mode of the camera.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@MO{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@MO{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -180,7 +174,7 @@ def __init__( self, description = 'Sets the output offset in GL at 12 bit internal resolution', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@OFS{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@OFS{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -188,7 +182,7 @@ def __init__( self, description = 'Sets the output resolution of the camera.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@OR{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@OR{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -196,7 +190,7 @@ def __init__( self, description = 'Selects display of the test pattern', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@TP{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@TP{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -204,7 +198,7 @@ def __init__( self, description = 'Sets the image output binning', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@VBIN{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@VBIN{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -212,7 +206,7 @@ def __init__( self, description = 'Sets the gain for the Red, Green and Blue channel', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}\r') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' )) self.add(pr.LocalVariable( @@ -220,7 +214,7 @@ def __init__( self, description = 'Sets the gain for the Red, Green and Blue channel', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}\r') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' )) self.add(pr.LocalVariable( @@ -228,7 +222,7 @@ def __init__( self, description = 'Sets the gain for the Red, Green and Blue channel', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}\r') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' )) self.add(pr.LocalVariable( @@ -236,7 +230,7 @@ def __init__( self, description = 'Sets the black level.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@BL{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@BL{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -244,7 +238,7 @@ def __init__( self, description = 'Enableling and disableling the vertical remap is done by means of the vertical remap command.', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@VR{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@VR{value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -256,7 +250,7 @@ def __init__( self, ''', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'@FSP{value}\r') if value!='' else '' + localSet = lambda value: self._tx.sendString(f'@FSP{value}') if value!='' else '' )) else: From 4e661a250f8f576347e4eaf4894ee2d4b8879569 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 21 Mar 2019 17:36:44 -0700 Subject: [PATCH 38/92] bug fix --- python/surf/protocols/clink/_UartPiranha4.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/python/surf/protocols/clink/_UartPiranha4.py b/python/surf/protocols/clink/_UartPiranha4.py index e1063aa72a..544780f95e 100644 --- a/python/surf/protocols/clink/_UartPiranha4.py +++ b/python/surf/protocols/clink/_UartPiranha4.py @@ -239,8 +239,8 @@ def __init__( self, description = 'Set baud rate', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'sbr {value}') if value!='' else '' units = 'bps', + localSet = lambda value: self._tx.sendString(f'sbr {value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -269,11 +269,11 @@ def __init__( self, self.add(pr.LocalVariable( name = 'SET', - description = 'Set internal exposure time in nanoseconds – 25 ns resolution', + description = 'Set internal exposure time in nanoseconds (25 ns resolution)', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'set {value}') if value!='' else '' units = '25ns', + localSet = lambda value: self._tx.sendString(f'set {value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -294,7 +294,7 @@ def __init__( self, self.add(pr.LocalVariable( name = 'SSB', - description = 'Set contrast offset – single value added to all pixels after PRNU/flat field coefficients (before gain).', + description = 'Set contrast offset - single value added to all pixels after PRNU/flat field coefficients (before gain).', mode = 'RW', value = '', localSet = lambda value: self._tx.sendString(f'ssb {value}') if value!='' else '' @@ -305,8 +305,8 @@ def __init__( self, description = 'Set internal line rate in Hz', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString(f'ssf {value}') if value!='' else '' units = 'Hz', + localSet = lambda value: self._tx.sendString(f'ssf {value}') if value!='' else '' )) self.add(pr.LocalVariable( @@ -370,8 +370,8 @@ def __init__( self, description = 'Display internal temperature in degrees Celsius', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString('vt') if value!='' else '' units = 'degC', + localSet = lambda value: self._tx.sendString('vt') if value!='' else '' )) self.add(pr.LocalVariable( @@ -379,7 +379,7 @@ def __init__( self, description = 'Display supply voltage', mode = 'RW', value = '', - localSet = lambda value: self._tx.sendString('vv') if value!='' else '' units = 'V', + localSet = lambda value: self._tx.sendString('vv') if value!='' else '' )) \ No newline at end of file From a3bf24deb2dd8bf25c3998192c70e7957cf357af Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 22 Mar 2019 10:16:37 -0700 Subject: [PATCH 39/92] Make GitHashShort a string --- python/surf/axi/_AxiVersion.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index 4eb04ff66c..825aee0876 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -192,9 +192,8 @@ def UserRst(): self.add(pr.LinkVariable( name = 'GitHashShort', mode = 'RO', - variable = self.GitHash, - disp = '{:07x}', - linkedGet = lambda read: self.GitHash.get(read) >> 132, + dependencies = [self.GitHash], + linkedGet = lambda read: f'{(self.GitHash.get(read) >> 132):x}', )) self.add(pr.RemoteVariable( From e3b52d2c8453583e7aa3a4e92cf7b8c692d05728 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 22 Mar 2019 12:40:09 -0700 Subject: [PATCH 40/92] python updates --- python/surf/protocols/clink/_ClinkChannel.py | 1 + python/surf/protocols/clink/_UartOpal000.py | 1 + python/surf/protocols/clink/_UartPiranha4.py | 57 ++++++++------------ 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 8394806e3f..32edcd8dcc 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -120,6 +120,7 @@ def __init__( self, offset = 0x10, bitSize = 16, bitOffset = 16, + disp = '{}', mode = "RW", units = "microsec", )) diff --git a/python/surf/protocols/clink/_UartOpal000.py b/python/surf/protocols/clink/_UartOpal000.py index d6729477f5..51f0bef691 100644 --- a/python/surf/protocols/clink/_UartOpal000.py +++ b/python/surf/protocols/clink/_UartOpal000.py @@ -18,6 +18,7 @@ #----------------------------------------------------------------------------- import pyrogue as pr +import rogue.interfaces.stream import surf.protocols.clink as clink diff --git a/python/surf/protocols/clink/_UartPiranha4.py b/python/surf/protocols/clink/_UartPiranha4.py index 544780f95e..103ccb18ad 100644 --- a/python/surf/protocols/clink/_UartPiranha4.py +++ b/python/surf/protocols/clink/_UartPiranha4.py @@ -18,6 +18,7 @@ #----------------------------------------------------------------------------- import pyrogue as pr +import rogue.interfaces.stream import surf.protocols.clink as clink @@ -114,12 +115,10 @@ def __init__( self, localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'GCP', description = 'Display current value of camera configuration parameters', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString('gcp') if value!='' else '' + function = lambda cmd: self._tx.sendString('gcp') )) self.add(pr.LocalVariable( @@ -130,12 +129,10 @@ def __init__( self, localSet = lambda value: self._tx.sendString(f'get {value}') if value!='' else '' )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'H', description = 'Display list of three letter commands', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString('h') if value!='' else '' + function = lambda cmd: self._tx.sendString('h') )) self.add(pr.LocalVariable( @@ -146,20 +143,10 @@ def __init__( self, localSet = lambda value: self._tx.sendString(f'lpc {value}') if value!='' else '' )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'RC', description = 'Resets the camera to the saved user default settings. These settings are saved using the usd command.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString('rc') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'ROI', - description = 'Flat field region of interest', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' + function = lambda cmd: self._tx.sendString('rc') )) self.add(pr.LocalVariable( @@ -178,12 +165,10 @@ def __init__( self, localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'RPC', description = 'Reset all user FPN values to zero and all user PRNU coefficients to one', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString('rpc') if value!='' else '' + function = lambda cmd: self._tx.sendString('rpc') )) self.add(pr.LocalVariable( @@ -365,21 +350,21 @@ def __init__( self, localSet = lambda value: self._tx.sendString(f'uss {value}') if value!='' else '' )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'VT', description = 'Display internal temperature in degrees Celsius', - mode = 'RW', - value = '', - units = 'degC', - localSet = lambda value: self._tx.sendString('vt') if value!='' else '' + function = lambda cmd: self._tx.sendString('vt'), )) - self.add(pr.LocalVariable( + self.add(pr.BaseCommand( name = 'VV', description = 'Display supply voltage', - mode = 'RW', - value = '', - units = 'V', - localSet = lambda value: self._tx.sendString('vv') if value!='' else '' - )) - \ No newline at end of file + function = lambda cmd: self._tx.sendString('vv'), + )) + + self.add(pr.BaseCommand( + name = 'SendEscape', + description = 'Send the Escape Char', + function = lambda cmd: self._tx.sendEscape() + )) + \ No newline at end of file From c256a2832fa7edf82b00246a34c3b94153e7c8f2 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 22 Mar 2019 13:21:28 -0700 Subject: [PATCH 41/92] adding Lmk61e2.py & Pca9535.py --- python/surf/devices/ti/_Lmk61e2.py | 497 +++++++++++++++++++++++++++++ python/surf/devices/ti/_Pca9535.py | 74 +++++ python/surf/devices/ti/__init__.py | 20 +- 3 files changed, 582 insertions(+), 9 deletions(-) create mode 100644 python/surf/devices/ti/_Lmk61e2.py create mode 100644 python/surf/devices/ti/_Pca9535.py diff --git a/python/surf/devices/ti/_Lmk61e2.py b/python/surf/devices/ti/_Lmk61e2.py new file mode 100644 index 0000000000..fad6221ad0 --- /dev/null +++ b/python/surf/devices/ti/_Lmk61e2.py @@ -0,0 +1,497 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# Title : PyRogue Lmk61e2 Module +#----------------------------------------------------------------------------- +# File : Lmk61e2.py +# Created : 2017-04-12 +#----------------------------------------------------------------------------- +# Description: +# PyRogue Lmk61e2 Module +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class Lmk61e2(pr.Device): + def __init__( self, + name = "Lmk61e2", + description = "Lmk61e2 Module", + **kwargs): + + super().__init__(name=name,description=description,**kwargs) + + self.add(pr.RemoteVariable( + name = 'VNDRID_BY[1]', + description = 'VNDRID_BY1 and VNDRID_BY0 registers are used to store the unique 16-bit Vendor Identification number assigned to I2C vendors.', + offset = (0 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'VNDRID_BY[0]', + description = 'VNDRID_BY0 and VNDRID_BY0 registers are used to store the unique 16-bit Vendor Identification number assigned to I2C vendors.', + offset = (1 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'PRODID', + description = 'The Product Identification Number is a unique 8-bit identification number used to identify the LMK61E2.', + offset = (2 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'REVID', + description = 'The REVID register is used to identify the LMK61E2 mask revision', + offset = (3 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'SLAVEADR', + description = 'The SLAVEADR register reflects the 7-bit I2C Slave Address value initialized from from on-chip EEPROM', + offset = (8 << 2), + bitSize = 7, + bitOffset = 1, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'EEREV', + description = 'The EEREV register provides an EEPROM image revision record. EEPROM Image Revision is automatically retrieved from EEPROM and stored in the EEREV register after a reset or after a EEPROM commit operation.', + offset = (9 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'AUTOSTRT', + description = 'Autostart. If AUTOSTRT is set to 1 the device will automatically attempt to achieve lock and enable outputs after a device reset. A device reset can be triggered by the power-on-reset, RESETn pin or by writing to the RESETN_SW bit. If AUTOSTRT is 0 then the device will halt after the configuration phase, a subsequent write to set the AUTOSTRT bit to 1 will trigger the PLL Lock sequence.', + offset = (10 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'ENCAL', + description = 'Enable Frequency Calibration. Triggers PLL/VCO calibration on both PLLs in parallel on 0 –> 1 transition of ENCAL. This bit is self-clearing and set to a 0 after PLL/VCO calibration is complete. In powerup or software rest mode, AUTOSTRT takes precedence.', + offset = (10 << 2), + bitSize = 1, + bitOffset = 1, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_PDN', + description = 'PLL Powerdown. The PLL_PDN bit determines whether PLL is automatically enabled and calibrated after a hardware reset. If the PLL_PDN bit is set to 1 during normal operation then PLL is disabled and the calibration circuit is reset. When PLL_PDN is then cleared to 0 PLL is re-enabled and the calibration sequence is automatically restarted.', + offset = (10 << 2), + bitSize = 1, + bitOffset = 6, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'XO_CAPCTRL_BY[1]', + description = 'XO Offset Value bits [1:0]', + offset = (16 << 2), + bitSize = 2, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'XO_CAPCTRL_BY[0]', + description = 'XO Offset Value bits[9:2]', + offset = (17 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OUT_SEL', + description = 'Channel Output Driver Format Select', + offset = (21 << 2), + bitSize = 2, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'DIFF_OUT_PD', + description = 'Power down differential output buffer.', + offset = (21 << 2), + bitSize = 1, + bitOffset = 7, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OUTDIV_BY[1]', + description = 'Channel\'s Output Divider Byte 1 (Bit 8). The Channel Divider, OUT_DIV, is a 9-bit divider', + offset = (22 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OUTDIV_BY[0]', + description = 'Channel\'s Output Divider Byte 0 (Bits 7-0).', + offset = (23 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_NDIV_BY[1]', + description = 'PLL N Divider Byte 1. PLL Integer N Divider bits [11:8].', + offset = (25 << 2), + bitSize = 4, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_NDIV_BY[0]', + description = 'PLL N Divider Byte 0. PLL Integer N Divider bits [7:0].', + offset = (26 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACNUM_BY[2]', + description = 'PLL Fractional Divider Numerator Byte 2. Bits [21:16]', + offset = (27 << 2), + bitSize = 6, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACNUM_BY[1]', + description = 'PLL Fractional Divider Numerator Byte 1. Bits [15:8].', + offset = (28 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACNUM_BY[0]', + description = 'PLL Fractional Divider Numerator Byte 0. Bits [7:0].', + offset = (29 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACDEN_BY[2]', + description = 'PLL Fractional Divider Denominator Byte 2. Bits [21:16]', + offset = (30 << 2), + bitSize = 6, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACDEN_BY[1]', + description = 'PLL Fractional Divider Denominator Byte 1. Bits [15:8].', + offset = (31 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_FRACDEN_BY[0]', + description = 'PLL Fractional Divider Denominator Byte 0. Bits [7:0].', + offset = (32 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_ORDER', + description = 'Mash Engine Order.', + offset = (33 << 2), + bitSize = 2, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_DTHRMODE', + description = 'Mash Engine dither mode control.', + offset = (33 << 2), + bitSize = 2, + bitOffset = 2, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_CP', + description = 'PLL Charge Pump Current', + offset = (34 << 2), + bitSize = 4, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_D', + description = 'PLL R Divider Frequency Doubler Enable. If PLL_D is 1 the R Divider Frequency Doubler is enabled.', + offset = (34 << 2), + bitSize = 1, + bitOffset = 5, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_ENABLE_C3', + description = 'Disable third order capacitor in the low pass filter.', + offset = (35 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_CP_PHASE_SHIFT', + description = 'Program Charge Pump Phase Shift.', + offset = (35 << 2), + bitSize = 3, + bitOffset = 4, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_LF_R2', + description = 'PLL Loop Filter R2.', + offset = (36 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_LF_C1', + description = 'PLL Loop Filter C1. The value in pF is given by 5 + 50 * PLL_LF_C1 (in decimal).', + offset = (37 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_LF_R3', + description = 'PLL Loop Filter R3', + offset = (38 << 2), + bitSize = 7, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_LF_C3', + description = 'PLL Loop Filter C3', + offset = (39 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_VCOWAIT', + description = 'VCO Wait Period', + offset = (42 << 2), + bitSize = 2, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'PLL_CLSDWAIT', + description = 'Closed Loop Wait Period', + offset = (42 << 2), + bitSize = 2, + bitOffset = 2, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMSCRC', + description = 'The NVMSCRC register holds the Stored CRC (Cyclic Redundancy Check) byte that has been retreived from onchip EEPROM', + offset = (47 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'NVMCNT', + description = 'The NVMCNT register is intended to reflect the number of on-chip EEPROM Erase/Program cycles that have taken place in EEPROM. The count is automatically incremented by hardware and stored in EEPROM.', + offset = (48 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'NVMPROG', + description = 'EEPROM Program Start. The NVMPROG bit is used to begin an on-chip EEPROM Program cycle. The Program cycle is only initiated if the immediately preceding I2C transaction was a write to the NVMUNLK register with the appropriate code. The NVMPROG bit is automatically cleared to 0. If the NVMERASE and NVMPROG bits are set simultaneously then an ERASE/PROGRAM cycle will be executed The EEPROM Program operation takes around 115ms', + offset = (49 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMERASE', + description = 'EEPROM Erase Start. The NVMERASE bit is used to begin an on-chip EEPROM Erase cycle. The Erase cycle is only initiated if the immediately preceding I2C transaction was a write to the NVMUNLK register with the appropriate code. The NVMERASE bit is automatically cleared to 0. The EEPROM Erase operation takes around 115ms.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 1, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMBUSY', + description = 'EEPROM Program Busy Indication. The NVMBUSY bit is 1 during an on-chip EEPROM Erase/Program cycle. While NVMBUSY is 1 the on-chip EEPROM cannot be accessed.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 2, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'NVMCOMMIT', + description = 'EEPROM Commit to Registers. The NVMCOMMIT bit is used to initiate a transfer of the on-chip EEPROM contents to internal registers. The transfer happens automatically after reset or when NVMCOMMIT is set to 1. The NVMCOMMIT bit is automatically cleared to 0. The I2C registers cannot be read while a EEPROM Commit operation is taking place.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 3, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMAUTOCRC', + description = 'EEPROM Automatic CRC. When NVMAUTOCRC is 1 then the EEPROM Stored CRC byte is automatically calculated whenever a EEPROM program takes place.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 4, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMCRCERR', + description = 'EEPROM CRC Error Indication. The NVMCRCERR bit is set to 1 if a CRC Error has been detected when reading back from on-chip EEPROM during device configuration.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 5, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'REGCOMMIT', + description = 'REG Commit to EEPROM SRAM Array. The REGCOMMIT bit is used to initiate a transfer from the on-chip registers back to the corresponding location in the EEPROM SRAM Array. The REGCOMMIT bit is automatically cleared to 0 when the transfer is complete.', + offset = (49 << 2), + bitSize = 1, + bitOffset = 6, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMLCRC', + description = '', + offset = (50 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'MEMADR', + description = 'Memory Address. The MEMADR value determines the starting address for on-chip SRAM read/write access or on-chip EEPROM access. The internal address to access SRAM or EEPROM is automatically incremented; however the MEMADR register does not reflect the internal address in this way. When the SRAM or EEPROM arrays are accessed using the I2C interface only bits [4:0] of MEMADR are used to form the byte Wise address.', + offset = (51 << 2), + bitSize = 7, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMDAT', + description = 'EEPROM Read Data. The first time an I2C read transaction accesses the NVMDAT register address, either because it was explicitly targeted or because the address was autoincremented, the read transaction will return the EEPROM data located at the address specified by the MEMADR register. Any additional read\'s which are part of the same transaction will cause the EEPROM address to be incremented and the next EEPROM data byte will be returned. The I2C address will no longer be auto-incremented, i.e the I2C address will be locked to the NVMDAT register after the first access. Access to the NVMDAT register will terminate at the end of the current I2C transaction.', + offset = (52 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'RAMDAT', + description = 'RAM Read/Write Data. The first time an I2C read or write transaction accesses the RAMDAT register address, either because it was explicitly targeted or because the address was auto-incremented, a read transaction will return the RAM data located at the address specified by the MEMADR register and a write transaction will cause the current I2C data to be written to the address specified by the MEMADR register. Any additional accesses which are part of the same transaction will cause the RAM address to be incremented and a read or write access will take place to the next SRAM address. The I2C address will no longer be auto-incremented, i.e the I2C address will be locked to the RAMDAT register after the first access. Access to the RAMDAT register will terminate at the end of the current I2C transaction.', + offset = (53 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NVMUNLK', + description = 'EEPROM Prog Unlock. The NVMUNLK register must be written immediately prior to setting the NVMPROG bit of register NVMCTL, otherwise the Erase/Program cycle will not be triggered. NVMUNLK must be written with a value of 0xBE.', + offset = (56 << 2), + bitSize = 8, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'CAL', + description = 'Calibration Active PLL.', + offset = (66 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'LOL', + description = 'Loss of Lock PLL.', + offset = (66 << 2), + bitSize = 1, + bitOffset = 1, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'SWR2PLL', + description = 'Software Reset PLL. Setting SWR2PLL to 1 resets the PLL calibrator and clock dividers. This bit is automatically cleared to 0.', + offset = (72 << 2), + bitSize = 1, + bitOffset = 1, + mode = 'RW', + )) + \ No newline at end of file diff --git a/python/surf/devices/ti/_Pca9535.py b/python/surf/devices/ti/_Pca9535.py new file mode 100644 index 0000000000..485936e0f1 --- /dev/null +++ b/python/surf/devices/ti/_Pca9535.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# Title : PyRogue Pca9535 Module +#----------------------------------------------------------------------------- +# File : Pca9535.py +# Created : 2017-04-12 +#----------------------------------------------------------------------------- +# Description: +# PyRogue Pca9535 Module +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class Pca9535(pr.Device): + def __init__( self, + name = "Pca9535", + description = "Pca9535 Module", + **kwargs): + + super().__init__(name=name,description=description,**kwargs) + + self.addRemoteVariables( + name = 'Input', + description = 'Input Port', + offset = (0x00 << 2), + number = 2, + bitSize = 8, + bitOffset = 0, + stride = 4, + mode = "RO", + pollInterval = 1, + ) + + self.addRemoteVariables( + name = 'Output', + description = 'Output Port', + offset = (0x02 << 2), + number = 2, + bitSize = 8, + bitOffset = 0, + stride = 4, + mode = "RW", + ) + + self.addRemoteVariables( + name = 'Polarity', + description = 'Polarity Inversion Port', + offset = (0x04 << 2), + number = 2, + bitSize = 8, + bitOffset = 0, + stride = 4, + mode = "RW", + ) + + self.addRemoteVariables( + name = 'Config', + description = 'Configuration Port', + offset = (0x06 << 2), + number = 2, + bitSize = 8, + bitOffset = 0, + stride = 4, + mode = "RW", + ) + \ No newline at end of file diff --git a/python/surf/devices/ti/__init__.py b/python/surf/devices/ti/__init__.py index 87c42e0e24..123a1c5866 100644 --- a/python/surf/devices/ti/__init__.py +++ b/python/surf/devices/ti/__init__.py @@ -8,12 +8,14 @@ ## may be copied, modified, propagated, or distributed except according to ## the terms contained in the LICENSE.txt file. ############################################################################## -from surf.devices.ti._Adc16Dx370 import * -from surf.devices.ti._Adc32Rf45 import * -from surf.devices.ti._Adc32Rf45Channel import * -from surf.devices.ti._Ads42Lbx9 import * -from surf.devices.ti._Ads54J60 import * -from surf.devices.ti._Ads54J60Channel import * -from surf.devices.ti._AxiCdcm6208 import * -from surf.devices.ti._Dac38J84 import * -from surf.devices.ti._Lmk04828 import * +from surf.devices.ti._Adc16Dx370 import * +from surf.devices.ti._Adc32Rf45 import * +from surf.devices.ti._Adc32Rf45Channel import * +from surf.devices.ti._Ads42Lbx9 import * +from surf.devices.ti._Ads54J60 import * +from surf.devices.ti._Ads54J60Channel import * +from surf.devices.ti._AxiCdcm6208 import * +from surf.devices.ti._Dac38J84 import * +from surf.devices.ti._Lmk04828 import * +from surf.devices.ti._Lmk61e2 import * +from surf.devices.ti._Pca9535 import * From 9421dc2b9d26e37502421c18c242714179a78e0b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 22 Mar 2019 13:21:44 -0700 Subject: [PATCH 42/92] Si5345.py for rawWrite() overlap exceptions --- python/surf/devices/silabs/_Si5345.py | 799 +++++++++++++++++--------- 1 file changed, 529 insertions(+), 270 deletions(-) diff --git a/python/surf/devices/silabs/_Si5345.py b/python/surf/devices/silabs/_Si5345.py index ea16626292..1216f8b53d 100644 --- a/python/surf/devices/silabs/_Si5345.py +++ b/python/surf/devices/silabs/_Si5345.py @@ -35,7 +35,7 @@ def __init__(self, name = "CsvFilePath", description = "Used if command's argument is empty", mode = "RW", - value = "", + value = "", )) ############################## @@ -80,15 +80,15 @@ def LoadCsvFile(arg): ############################## # Devices ############################## - self.add(Si5345Page0(offset=0x0,simpleDisplay=simpleDisplay,expand=False)) - self.add(Si5345Page1(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page2(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page3(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page4(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page5(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page9(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345PageA(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345PageB(offset=0x0,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page0(offset=0x000,simpleDisplay=simpleDisplay,expand=False)) + self.add(Si5345Page1(offset=0x100,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page2(offset=0x200,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page3(offset=0x300,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page4(offset=0x400,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page5(offset=0x500,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page9(offset=0x900,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345PageA(offset=0xA00,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345PageB(offset=0xB00,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) class Si5345Page0(pr.Device): def __init__(self, @@ -105,23 +105,25 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'PN_BASE_LO', description = 'Four-digit base part number, one nibble per digit.', - offset = (0x0002 << 2), + offset = (0x02 << 2), bitSize = 8, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'PN_BASE_HI', description = 'Four-digit base part number, one nibble per digit.', - offset = (0x0003 << 2), + offset = (0x03 << 2), bitSize = 8, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'GRADE', description = 'One ASCII character indicating the device speed/synthesis mode.', - offset = (0x0004 << 2), + offset = (0x04 << 2), bitSize = 8, mode = 'RO', enum = { @@ -130,12 +132,13 @@ def __init__(self, 0x2: 'C', 0x3: 'D', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'DEVICE_REV', description = 'One ASCII character indicating the device revision level.', - offset = (0x0005 << 2), + offset = (0x05 << 2), bitSize = 8, mode = 'RO', enum = { @@ -144,478 +147,525 @@ def __init__(self, 0x2: 'C', 0x3: 'D', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'TOOL_VERSION[0]', description = 'The software tool version that creates the register values downloaded at power up is represented by TOOL_VERSION.', - offset = (0x0006 << 2), + offset = (0x06 << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'TOOL_VERSION[1]', description = 'The software tool version that creates the register values downloaded at power up is represented by TOOL_VERSION.', - offset = (0x0007 << 2), + offset = (0x07 << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'TOOL_VERSION[2]', description = 'The software tool version that creates the register values downloaded at power up is represented by TOOL_VERSION.', - offset = (0x0008 << 2), + offset = (0x08 << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'TEMP_GRADE', description = 'Device temperature grading, 0 = Industrial (40 C to 85 C) ambient conditions', - offset = (0x0009 << 2), + offset = (0x09 << 2), bitSize = 8, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'PKG_ID', description = 'Package ID, 0 = 9x9 mm 64 QFN', - offset = (0x000A << 2), + offset = (0x0A << 2), bitSize = 8, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'I2C_ADDR', description = 'The upper five bits of the 7-bit I2C address.', - offset = (0x000B << 2), + offset = (0x0B << 2), bitSize = 7, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SYSINCAL', description = '1 if the device is calibrating.', - offset = (0x000C << 2), + offset = (0x0C << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSXAXB', description = '1 if there is no signal at the XAXB pins.', - offset = (0x000C << 2), + offset = (0x0C << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'XAXB_ERR', description = '1 if there is a problem locking to the XAXB input signal.', - offset = (0x000C << 2), + offset = (0x0C << 2), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SMBUS_TIMEOUT', description = '1 if there is an SMBus timeout error.', - offset = (0x000C << 2), + offset = (0x0C << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS', description = '1 if the clock input is currently LOS', - offset = (0x000D << 2), + offset = (0x0D << 2), bitSize = 4, bitOffset = 0, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF', description = '1 if the clock input is currently OOF', - offset = (0x000D << 2), + offset = (0x0D << 2), bitSize = 4, bitOffset = 4, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL', description = '1 if the DSPLL is out of lock', - offset = (0x000E << 2), + offset = (0x0E << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD', description = '1 if the DSPLL is in holdover (or free run)', - offset = (0x000E << 2), + offset = (0x0E << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'CAL_PLL', description = '1 if the DSPLL internal calibration is busy', - offset = (0x000F << 2), + offset = (0x0F << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteCommand( name = 'ClearIntErrFlag', description = 'command to clears the internal error flags', - offset = (0x0011 << 2), + offset = (0x11 << 2), bitSize = 1, function = lambda cmd: cmd.post(0), + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SYSINCAL_FLG', description = 'Sticky version of SYSINCAL. Write a 0 to this bit to clear.', - offset = (0x0011 << 2), + offset = (0x11 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSXAXB_FLG', description = 'Sticky version of LOSXAXB. Write a 0 to this bit to clear.', - offset = (0x0011 << 2), + offset = (0x11 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'XAXB_ERR_FLG', description = 'Sticky version of XAXB_ERR. Write a 0 to this bit to clear.', - offset = (0x0011 << 2), + offset = (0x11 << 2), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RO', pollInterval = 1, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SMBUS_TIMEOUT_FLG', description = 'Sticky version of SMBUS_TIMEOUT. Write a 0 to this bit to clear.', - offset = (0x0011 << 2), + offset = (0x11 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS_FLG', description = '1 if the clock input is LOS for the given input', - offset = (0x0012 << 2), + offset = (0x12 << 2), bitSize = 4, bitOffset = 0, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_FLG', description = '1 if the clock input is OOF for the given input', - offset = (0x0012 << 2), + offset = (0x12 << 2), bitSize = 4, bitOffset = 4, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FLG', description = '1 if the DSPLL was unlocked', - offset = (0x0013 << 2), + offset = (0x13 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_FLG', description = '1 if the DSPLL was in holdover or free run', - offset = (0x0013 << 2), + offset = (0x13 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'CAL_PLL_FLG', description = '1 if the internal calibration was busy', - offset = (0x0014 << 2), + offset = (0x14 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_ON_HOLD', description = 'Set by CBPro.', - offset = (0x0016 << 2), + offset = (0x16 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SYSINCAL_INTR_MSK', description = '1 to mask SYSINCAL_FLG from causing an interrupt', - offset = (0x0017 << 2), + offset = (0x17 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSXAXB_INTR_MSK', description = '1 to mask the LOSXAXB_FLG from causing an interrupt', - offset = (0x0017 << 2), + offset = (0x17 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SMBUS_TIMEOUT_FLG_MSK', description = '1 to mask SMBUS_TIMEOUT_FLG from the interrupt', - offset = (0x0017 << 2), + offset = (0x17 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'STATUS_FLG_RESERVED', description = 'Factory set to 1 to mask reserved bit from causing an interrupt. Do not clear this bit.', - offset = (0x0017 << 2), + offset = (0x17 << 2), bitSize = 2, bitOffset = 6, mode = 'WO', value = 0x3, hidden = True, verify = False, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS_INTR_MSK', description = '1 to mask the clock input LOS flag', - offset = (0x0018 << 2), + offset = (0x18 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_INTR_MSK', description = '1 to mask the clock input OOF flag', - offset = (0x0018 << 2), + offset = (0x18 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_INTR_MSK', description = '1 to mask the clock input LOL flag', - offset = (0x0019 << 2), + offset = (0x19 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_INTR_MSK', description = '1 to mask the holdover flag', - offset = (0x0019 << 2), + offset = (0x19 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'CAL_INTR_MSK', description = '1 to mask the DSPLL internal calibration busy flag', - offset = (0x001A << 2), + offset = (0x1A << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteCommand( name = "SOFT_RST_ALL", description = "Initialize and calibrates the entire device", - offset = (0x001C << 2), + offset = (0x1C << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteCommand( name = "SOFT_RST", description = "Initialize outer loop", - offset = (0x001C << 2), + offset = (0x1C << 2), bitSize = 1, bitOffset = 2, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteCommand( name = "FINC", description = "1 a rising edge will cause the selected MultiSynth to increment the output frequency by the Nx_FSTEPW parameter. See registers 0x03390x0358", - offset = (0x001D << 2), + offset = (0x1D << 2), bitSize = 1, bitOffset = 0, function = pr.BaseCommand.toggle, hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteCommand( name = "FDEC", description = "1 a rising edge will cause the selected MultiSynth to decrement the output frequency by the Nx_FSTEPW parameter. See registers 0x03390x0358", - offset = (0x001D << 2), + offset = (0x1D << 2), bitSize = 1, bitOffset = 1, function = pr.BaseCommand.toggle, hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'PDN', description = '1 to put the device into low power mode', - offset = (0x001E << 2), + offset = (0x1E << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HARD_RST', description = '1 causes hard reset. The same as power up except that the serial port access is not held at reset.', - offset = (0x001E << 2), + offset = (0x1E << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "SYNC", description = "1 to reset all output R dividers to the same state.", - offset = (0x001E << 2), + offset = (0x1E << 2), bitSize = 1, bitOffset = 2, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SPI_3WIRE', description = '0 for 4-wire SPI, 1 for 3-wire SPI', - offset = (0x002B << 2), + offset = (0x2B << 2), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'AUTO_NDIV_UPDATE', description = 'Set by CBPro.', - offset = (0x002B << 2), + offset = (0x2B << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS_EN', description = '1 to enable LOS for a clock input', - offset = (0x002C << 2), + offset = (0x2C << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSXAXB_DIS', description = '0: Enable LOS Detection (default)', - offset = (0x002C << 2), + offset = (0x2C << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'LOS_VAL_TIME[{i}]', description = f'Clock Input[{i}]', - offset = (0x002D << 2), + offset = (0x2D << 2), bitSize = 2, bitOffset = (2*i), mode = 'RW', @@ -625,24 +675,27 @@ def __init__(self, 0x2: '200ms', 0x3: '1000ms', }, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'LOS_TRG_THR_LO[{i}]', description = 'Trigger Threshold 16-bit Threshold Value', - offset = ((0x002E+(2*i)) << 2), + offset = ((0x2E+(2*i)) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'LOS_TRG_THR_HI[{i}]', description = 'Trigger Threshold 16-bit Threshold Value', - offset = ((0x002F+(2*i)) << 2), + offset = ((0x2F+(2*i)) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) @@ -650,44 +703,48 @@ def __init__(self, self.add(pr.RemoteVariable( name = f'LOS_CLR_THR_LO[{i}]', description = 'Clear Threshold 16-bit Threshold Value', - offset = ((0x0036+(2*i)) << 2), + offset = ((0x36+(2*i)) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'LOS_CLR_THR_HI[{i}]', description = 'Clear Threshold 16-bit Threshold Value', - offset = ((0x0037+(2*i)) << 2), + offset = ((0x37+(2*i)) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_EN', description = '1 to enable, 0 to disable', - offset = (0x003F << 2), + offset = (0x3F << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FAST_OOF_EN', description = '1 to enable, 0 to disable', - offset = (0x003F << 2), + offset = (0x3F << 2), bitSize = 4, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_REF_SEL', description = 'OOF Reference Select', - offset = (0x0040 << 2), + offset = (0x40 << 2), bitSize = 3, mode = 'RO', enum = { @@ -697,251 +754,276 @@ def __init__(self, 0x3: 'CLKIN3', 0x4: 'XAXB', }, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF_DIV_SEL[{i}]', description = 'Sets a divider for the OOF circuitry for each input clock 0,1,2,3. The divider value is 2OOFx_DIV_SEL. CBPro sets these dividers.', - offset = ((0x0041+i) << 2), + offset = ((0x41+i) << 2), bitSize = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOFXO_DIV_SEL', description = 'Sets a divider for the OOF circuitry for each input clock 0,1,2,3. The divider value is 2OOFx_DIV_SEL. CBPro sets these dividers.', - offset = (0x0045 << 2), + offset = (0x45 << 2), bitSize = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF_SET_THR[{i}]', description = 'OOF Set threshold. Range is up to 500 ppm in steps of 1/16 ppm.', - offset = ((0x0046+i) << 2), + offset = ((0x46+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF_CLR_THR[{i}]', description = 'OOF Clear threshold. Range is up to 500 ppm in steps of 1/16 ppm.', - offset = ((0x004A+i) << 2), + offset = ((0x4A+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_DETWIN_SEL[0]', description = 'Values calculated by CBPro.', - offset = (0x004E << 2), + offset = (0x4E << 2), bitSize = 3, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_DETWIN_SEL[1]', description = 'Values calculated by CBPro.', - offset = (0x004E << 2), + offset = (0x4E << 2), bitSize = 3, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_DETWIN_SEL[2]', description = 'Values calculated by CBPro.', - offset = (0x004F << 2), + offset = (0x4F << 2), bitSize = 3, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_DETWIN_SEL[3]', description = 'Values calculated by CBPro.', - offset = (0x004F << 2), + offset = (0x4F << 2), bitSize = 3, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_ON_LOS', description = 'Values set by CBPro', - offset = (0x0050 << 2), + offset = (0x50 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'FAST_OOF_SET_THR[{i}]', description = '(1+ value) x 1000 ppm', - offset = ((0x0051+i) << 2), + offset = ((0x51+i) << 2), bitSize = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'FAST_OOF_CLR_THR[{i}]', description = '(1+ value) x 1000 ppm', - offset = ((0x0055+i) << 2), + offset = ((0x55+i) << 2), bitSize = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'FAST_OOF_DETWIN_SEL[{i}]', description = 'Values calculated by CBPro.', - offset = (0x0059 << 2), + offset = (0x59 << 2), bitSize = 2, bitOffset = (2*i), mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF0_RATIO_REF[{i}]', description = 'Values calculated by CBPro.', - offset = ((0x005A+i) << 2), + offset = ((0x5A+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF1_RATIO_REF[{i}]', description = 'Values calculated by CBPro.', - offset = ((0x005E+i) << 2), + offset = ((0x5E+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF2_RATIO_REF[{i}]', description = 'Values calculated by CBPro.', - offset = ((0x0062+i) << 2), + offset = ((0x62+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF3_RATIO_REF[{i}]', description = 'Values calculated by CBPro.', - offset = ((0x0066+i) << 2), + offset = ((0x66+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FST_EN', description = 'Enables fast detection of LOL. A large input frequency error will quickly assert LOL when this is enabled.', - offset = (0x0092 << 2), + offset = (0x92 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FST_DETWIN_SEL', description = 'Values calculated by CBPro', - offset = (0x0093 << 2), + offset = (0x93 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FST_VALWIN_SEL', description = 'Values calculated by CBPro', - offset = (0x0095 << 2), + offset = (0x95 << 2), bitSize = 2, bitOffset = 2, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FST_SET_THR_SEL', description = 'Values calculated by CBPro', - offset = (0x0096 << 2), + offset = (0x96 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_FST_CLR_THR_SEL', description = 'Values calculated by CBPro', - offset = (0x0098 << 2), + offset = (0x98 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLOW_EN_PLL', description = '1 to enable LOL; 0 to disable LOL.', - offset = (0x009A << 2), + offset = (0x9A << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLW_DETWIN_SEL', description = '1 to enable LOL; 0 to disable LOL.', - offset = (0x009B << 2), + offset = (0x9B << 2), bitSize = 4, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLW_VALWIN_SEL', description = 'Values calculated by CBPro.', - offset = (0x009D << 2), + offset = (0x9D << 2), bitSize = 2, bitOffset = 2, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLW_SET_THR', description = 'Configures the loss of lock set thresholds', - offset = (0x009E << 2), + offset = (0x9E << 2), bitSize = 4, bitOffset = 4, mode = 'RW', @@ -958,12 +1040,13 @@ def __init__(self, 0x9: '3000 ppm', 0xA: '10000 ppm', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLW_CLR_THR', description = 'Configures the loss of lock set thresholds.', - offset = (0x00A0 << 2), + offset = (0xA0 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', @@ -980,32 +1063,35 @@ def __init__(self, 0x9: '3000 ppm', 0xA: '10000 ppm', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_TIMER_EN', description = '0 to disable, 1 to enable', - offset = (0x00A2 << 2), + offset = (0xA2 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'LOL_CLR_DELAY_DIV256[{i}]', description = 'Set by CBPro.', - offset = ((0x00A9+i) << 2), + offset = ((0xA9+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'ACTIVE_NVM_BANK', description = 'Read-only field indicating number of user bank writes carried out so far.', - offset = (0x00E2 << 2), + offset = (0xE2 << 2), bitSize = 8, bitOffset = 0, mode = 'RO', @@ -1015,184 +1101,202 @@ def __init__(self, 0x0F: 'two', 0x3F: 'three', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'NVM_WRITE', description = 'Write 0xC7 to initiate an NVM bank burn.', - offset = (0x00E3 << 2), + offset = (0xE3 << 2), bitSize = 8, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "NVM_READ_BANK", description = "When set, this bit will read the NVM down into the volatile memory.", - offset = (0x00E4 << 2), + offset = (0xE4 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_EXTEND_EN', description = 'Extend Fastlock bandwidth period past LOL Clear, 0: Do not extend Fastlock period, 1: Extend Fastlock period (default)', - offset = (0x00E5 << 2), + offset = (0xE5 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'FASTLOCK_EXTEND[{i}]', description = 'Set by CBPro.', - offset = ((0x00EA+i) << 2), + offset = ((0xEA+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'REG_0xF7_INTR', description = 'Set by CBPro.', - offset = (0x00F6 << 2), + offset = (0xF6 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'REG_0xF8_INTR', description = 'Set by CBPro.', - offset = (0x00F6 << 2), + offset = (0xF6 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'REG_0xF9_INTR', description = 'Set by CBPro.', - offset = (0x00F6 << 2), + offset = (0xF6 << 2), base = pr.Bool, bitSize = 1, bitOffset = 2, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SYSINCAL_INTR', description = 'Set by CBPro.', - offset = (0x00F7 << 2), + offset = (0xF7 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSXAXB_INTR', description = 'Set by CBPro.', - offset = (0x00F7 << 2), + offset = (0xF7 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSREF_INTR', description = 'Set by CBPro.', - offset = (0x00F7 << 2), + offset = (0xF7 << 2), base = pr.Bool, bitSize = 1, bitOffset = 2, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOSVCO_INTR', description = 'Set by CBPro.', - offset = (0x00F7 << 2), + offset = (0xF7 << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'SMBUS_TIME_OUT_INTR', description = 'Set by CBPro.', - offset = (0x00F7 << 2), + offset = (0xF7 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS_INTR', description = 'Set by CBPro.', - offset = (0x00F8 << 2), + offset = (0xF8 << 2), bitSize = 4, bitOffset = 0, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_INTR', description = 'Set by CBPro.', - offset = (0x00F8 << 2), + offset = (0xF8 << 2), bitSize = 4, bitOffset = 4, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_INTR', description = 'Set by CBPro.', - offset = (0x00F9 << 2), + offset = (0xF9 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_INTR', description = 'Set by CBPro.', - offset = (0x00F9 << 2), + offset = (0xF9 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'DEVICE_READY', description = 'Ready Only byte to indicate device is ready. When read data is 0x0F one can safely read/write registers. This register is repeated on every page therefore a page write is not ever required to read the DEVICE_READY status.', - offset = (0x00FE << 2), + offset = (0xFE << 2), bitSize = 8, bitOffset = 0, mode = 'RO', + overlapEn = True, )) class Si5345Page1(pr.Device): @@ -1210,48 +1314,52 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'OUTALL_DISABLE_LOW', description = '1 Pass through the output enables, 0 disables all output drivers', - offset = (0x0102 << 2), + offset = (0x02 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(10): self.add(pr.RemoteVariable( name = f'OUT_PDN[{i}]', description = 'Output driver: 0 to power up the regulator, 1 to power down the regulator. Clock outputs will be weakly pulled low.', - offset = ( ((0x0108+(5*i)) << 2) if (i!=9) else ((0x0108+(5*i)+5) << 2) ), + offset = ( ((0x08+(5*i)) << 2) if (i!=9) else ((0x08+(5*i)+5) << 2) ), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_OE[{i}]', description = 'Output driver: 0 to disable the output, 1 to enable the output', - offset = ( ((0x0108+(5*i)) << 2) if (i!=9) else ((0x0108+(5*i)+5) << 2) ), + offset = ( ((0x08+(5*i)) << 2) if (i!=9) else ((0x08+(5*i)+5) << 2) ), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_RDIV_FORCE2[{i}]', description = '0 R0 divider value is set by R0_REG, 1 R0 divider value is forced into divide by 2', - offset = ( ((0x0108+(5*i)) << 2) if (i!=9) else ((0x0108+(5*i)+5) << 2) ), + offset = ( ((0x08+(5*i)) << 2) if (i!=9) else ((0x08+(5*i)+5) << 2) ), base = pr.Bool, bitSize = 1, bitOffset = 2, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_FORMAT[{i}]', description = 'OUT_FORMAT', - offset = ( ((0x0109+(5*i)) << 2) if (i!=9) else ((0x0109+(5*i)+5) << 2) ), + offset = ( ((0x09+(5*i)) << 2) if (i!=9) else ((0x09+(5*i)+5) << 2) ), bitSize = 2, bitOffset = 0, mode = 'RW', @@ -1263,22 +1371,24 @@ def __init__(self, 0x5: 'LVCMOS (+pin only)', 0x6: 'LVCMOS (pin only)', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_SYNC_EN[{i}]', description = 'enable/disable synchronized (glitchless) operation. When enabled, the power down and output enables are synchronized to the output clock.', - offset = ( ((0x0109+(5*i)) << 2) if (i!=9) else ((0x0109+(5*i)+5) << 2) ), + offset = ( ((0x09+(5*i)) << 2) if (i!=9) else ((0x09+(5*i)+5) << 2) ), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_DIS_STATE[{i}]', description = 'Determines the state of an output driver when disabled', - offset = ( ((0x0109+(5*i)) << 2) if (i!=9) else ((0x0109+(5*i)+5) << 2) ), + offset = ( ((0x09+(5*i)) << 2) if (i!=9) else ((0x09+(5*i)+5) << 2) ), bitSize = 2, bitOffset = 4, mode = 'RW', @@ -1286,12 +1396,13 @@ def __init__(self, 0x0: 'Disable low', 0x1: 'Disable high', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_CMOS_DRV[{i}]', description = 'LVCMOS output impedance.', - offset = ( ((0x0109+(5*i)) << 2) if (i!=9) else ((0x0109+(5*i)+5) << 2) ), + offset = ( ((0x09+(5*i)) << 2) if (i!=9) else ((0x09+(5*i)+5) << 2) ), bitSize = 2, bitOffset = 6, mode = 'RW', @@ -1300,30 +1411,33 @@ def __init__(self, 0x1: 'CMOS2', 0x2: 'CMOS3', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_CM[{i}]', description = 'This field only applies when OUT0_FORMAT=1 or 2. See Table 6.10 Settings for LVDS, LVPECL, and HCSL on page 41 and 18. Setting the Differential Output Driver to Non-Standard Amplitudes for details of the settings.', - offset = ( ((0x010A+(5*i)) << 2) if (i!=9) else ((0x010A+(5*i)+5) << 2) ), + offset = ( ((0x0A+(5*i)) << 2) if (i!=9) else ((0x0A+(5*i)+5) << 2) ), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_AMPL[{i}]', description = 'This field only applies when OUT0_FORMAT=1, 2, or 3. See Table 5.5 Hitless Switching Enable Bit on page 22 and 18. Setting the Differential Output Driver to Non-Standard Amplitudes for details of the settings.', - offset = ( ((0x010A+(5*i)) << 2) if (i!=9) else ((0x010A+(5*i)+5) << 2) ), + offset = ( ((0x0A+(5*i)) << 2) if (i!=9) else ((0x0A+(5*i)+5) << 2) ), bitSize = 3, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_MUX_SEL[{i}]', description = 'Output driver 0 input mux select.This selects the source of the multisynth', - offset = ( ((0x010B+(5*i)) << 2) if (i!=9) else ((0x010B+(5*i)+5) << 2) ), + offset = ( ((0x0B+(5*i)) << 2) if (i!=9) else ((0x0B+(5*i)+5) << 2) ), bitSize = 3, bitOffset = 0, mode = 'RW', @@ -1334,22 +1448,24 @@ def __init__(self, 0x3: 'N3', 0x4: 'N4', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_VDD_SEL_EN[{i}]', description = '1 = Enable OUT0_VDD_SEL', - offset = ( ((0x010B+(5*i)) << 2) if (i!=9) else ((0x010B+(5*i)+5) << 2) ), + offset = ( ((0x0B+(5*i)) << 2) if (i!=9) else ((0x0B+(5*i)+5) << 2) ), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_VDD_SEL[{i}]', description = 'Must be set to the VDD0 voltage.', - offset = ( ((0x010B+(5*i)) << 2) if (i!=9) else ((0x010B+(5*i)+5) << 2) ), + offset = ( ((0x0B+(5*i)) << 2) if (i!=9) else ((0x0B+(5*i)+5) << 2) ), bitSize = 2, bitOffset = 4, mode = 'RW', @@ -1358,12 +1474,13 @@ def __init__(self, 0x1: '1.8 V', 0x2: '2.5 V', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'OUT_INV[{i}]', description = 'OUT_INV', - offset = ( ((0x010B+(5*i)) << 2) if (i!=9) else ((0x010B+(5*i)+5) << 2) ), + offset = ( ((0x0B+(5*i)) << 2) if (i!=9) else ((0x0B+(5*i)+5) << 2) ), bitSize = 2, bitOffset = 6, mode = 'RW', @@ -1373,100 +1490,110 @@ def __init__(self, 0x2: 'CLK and CLK inverted', 0x3: 'CLK inverted', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUTX_ALWAYS_ON[0]', description = 'This setting is managed by CBPro during zero delay mode.', - offset = (0x013F << 2), + offset = (0x3F << 2), bitSize = 8, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUTX_ALWAYS_ON[1]', description = 'This setting is managed by CBPro during zero delay mode.', - offset = (0x0140 << 2), + offset = (0x40 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_MSK', description = 'Set by CBPro.', - offset = (0x0141 << 2), + offset = (0x41 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_LOL_MSK', description = 'Set by CBPro.', - offset = (0x0141 << 2), + offset = (0x41 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_LOSXAXB_MSK', description = 'Determines if outputs are disabled during an LOSXAXB condition, 0: All outputs disabled on LOSXAXB, 1: All outputs remain enabled during LOSXAXB condition', - offset = (0x0141 << 2), + offset = (0x41 << 2), base = pr.Bool, bitSize = 1, bitOffset = 6, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_MSK_LOS_PFD', description = 'Set by CBPro.', - offset = (0x0141 << 2), + offset = (0x41 << 2), base = pr.Bool, bitSize = 1, bitOffset = 7, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_MSK_LOL', description = '0: LOL will disable all connected outputs, 1: LOL does not disable any outputs', - offset = (0x0142 << 2), + offset = (0x42 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_DIS_MSK_HOLD', description = 'Set by CBPro.', - offset = (0x0142 << 2), + offset = (0x42 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OUT_PDN_ALL', description = '0- no effect, 1- all drivers powered down', - offset = (0x0145 << 2), + offset = (0x45 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) class Si5345Page2(pr.Device): @@ -1484,7 +1611,7 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'PXAXB', description = 'Sets the prescale divider for the input clock on XAXB.', - offset = (0x0206 << 2), + offset = (0x06 << 2), bitSize = 2, bitOffset = 0, mode = 'RO', @@ -1494,366 +1621,405 @@ def __init__(self, 0x2: 'pre-scale value 4', 0x3: 'pre-scale value 8', }, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'P0_NUM[{i}]', description = 'P0 Divider Numerator', - offset = ((0x0208+i) << 2), + offset = ((0x08+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'P0_DEN[{i}]', description = 'P0 Divider Denominator', - offset = ((0x020E+i) << 2), + offset = ((0x0E+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'P1_NUM[{i}]', description = 'P1 Divider Numerator', - offset = ((0x0212+i) << 2), + offset = ((0x12+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'P1_DEN[{i}]', description = 'P1 Divider Denominator', - offset = ((0x0218+i) << 2), + offset = ((0x18+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'P2_NUM[{i}]', description = 'P2 Divider Numerator', - offset = ((0x021C+i) << 2), + offset = ((0x1C+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'P2_DEN[{i}]', description = 'P2 Divider Denominator', - offset = ((0x0222+i) << 2), + offset = ((0x22+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'P3_NUM[{i}]', description = 'P3 Divider Numerator', - offset = ((0x0226+i) << 2), + offset = ((0x26+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'P3_DEN[{i}]', description = 'P3 Divider Denominator', - offset = ((0x022C+i) << 2), + offset = ((0x2C+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'Px_UPDATE', description = '0 - No update for P-divider value, 1 - Update P-divider value', - offset = (0x0230 << 2), + offset = (0x30 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'P_FRACN_MODE[{i}]', description = 'input divider fractional mode. Must be set to 0xB for proper operation.', - offset = ((0x0231+i) << 2), + offset = ((0x31+i) << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = f'P_FRAC_EN[{i}]', description = 'input divider fractional enable, 0: Integer-only division, 1: Fractional (or Integer) division', - offset = ((0x0231+i) << 2), + offset = ((0x31+i) << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'MXAXB_NUM[{i}]', description = 'MXAXB Divider Numerator', - offset = ((0x0235+i) << 2), + offset = ((0x35+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'MXAXB_DEN[{i}]', description = 'MXAXB Divider Denominator', - offset = ((0x023B+i) << 2), + offset = ((0x3B+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "MXAXB_UPDATE", description = "Set to 1 to update the MXAXB_NUM and MXAXB_DEN values. A SOFT_RST may also be used to update these values.", - offset = (0x023F << 2), + offset = (0x3F << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R0_REG[{i}]', description = 'R0 Divider: divide value = (REG+1) x 2', - offset = ((0x024A+i) << 2), + offset = ((0x4A+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R1_REG[{i}]', description = 'R1 Divider: divide value = (REG+1) x 2', - offset = ((0x024D+i) << 2), + offset = ((0x4D+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R2_REG[{i}]', description = 'R2 Divider: divide value = (REG+1) x 2', - offset = ((0x0250+i) << 2), + offset = ((0x50+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R3_REG[{i}]', description = 'R3 Divider: divide value = (REG+1) x 2', - offset = ((0x0256+i) << 2), + offset = ((0x56+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R4_REG[{i}]', description = 'R4 Divider: divide value = (REG+1) x 2', - offset = ((0x0256+i) << 2), + offset = ((0x56+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R5_REG[{i}]', description = 'R5 Divider: divide value = (REG+1) x 2', - offset = ((0x0259+i) << 2), + offset = ((0x59+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R6_REG[{i}]', description = 'R6 Divider: divide value = (REG+1) x 2', - offset = ((0x025C+i) << 2), + offset = ((0x5C+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R7_REG[{i}]', description = 'R7 Divider: divide value = (REG+1) x 2', - offset = ((0x025F+i) << 2), + offset = ((0x5F+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R8_REG[{i}]', description = 'R8 Divider: divide value = (REG+1) x 2', - offset = ((0x0262+i) << 2), + offset = ((0x62+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'R9_REG[{i}]', description = 'R9 Divider: divide value = (REG+1) x 2', - offset = ((0x0268+i) << 2), + offset = ((0x68+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(8): self.add(pr.RemoteVariable( name = f'DESIGN_ID[{i}]', description = 'ASCII encoded string defined by CBPro user', - offset = ((0x026B+i) << 2), + offset = ((0x6B+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(8): self.add(pr.RemoteVariable( name = f'OPN_ID[{i}]', description = 'OPN unique identifier. ASCII encoded by CBPro user', - offset = ((0x0278+i) << 2), + offset = ((0x78+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OPN_REVISION', description = 'OPN_REVISION', - offset = (0x027D << 2), + offset = (0x7D << 2), bitSize = 8, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'BASELINE_ID', description = 'BASELINE_ID', - offset = (0x027E << 2), + offset = (0x7E << 2), bitSize = 8, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF_TRG_THR_EXT[{i}]', description = 'Set by CBPro.', - offset = ((0x028A+i) << 2), + offset = ((0x8A+i) << 2), bitSize = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'OOF_CLR_THR_EXT[{i}]', description = 'Set by CBPro.', - offset = ((0x028E+i) << 2), + offset = ((0x8E+i) << 2), bitSize = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_EXTEND_SCL', description = 'Scales LOLB_INT_TIMER_DIV256. Set by CBPro', - offset = (0x0294 << 2), + offset = (0x94 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_SLW_VALWIN_SELX', description = 'Set by CBPro.', - offset = (0x0296 << 2), + offset = (0x96 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_DLY_ONSW_EN', description = 'Set by CBPro.', - offset = (0x0297 << 2), + offset = (0x97 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_DLY_ONLOL_EN', description = 'Set by CBPro.', - offset = (0x0299 << 2), + offset = (0x99 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'FASTLOCK_DLY_ONLOL[{i}]', description = 'Set by CBPro.', - offset = ((0x029D+i) << 2), + offset = ((0x9D+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'FASTLOCK_DLY_ONSW[{i}]', description = 'Set by CBPro.', - offset = ((0x02A9+i) << 2), + offset = ((0xA9+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_NOSIG_TIME', description = 'Set by CBPro.', - offset = (0x02B7 << 2), + offset = (0xB7 << 2), bitSize = 2, bitOffset = 2, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOL_LOS_REFCLK', description = 'Set by CBPro.', - offset = (0x02B8 << 2), + offset = (0xB8 << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', hidden = simpleDisplay, + overlapEn = True, )) class Si5345Page3(pr.Device): @@ -1872,204 +2038,226 @@ def __init__(self, self.add(pr.RemoteVariable( name = f'N0_NUM[{i}]', description = 'N0 Numerator', - offset = ((0x0302+i) << 2), + offset = ((0x02+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'N0_DEN[{i}]', description = 'N0 Denominator', - offset = ((0x0308+i) << 2), + offset = ((0x08+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N0_UPDATE", description = "Set this bit to update the N0 divider.", - offset = (0x030C << 2), + offset = (0x0C << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, - )) + overlapEn = True, + )) for i in range(6): self.add(pr.RemoteVariable( name = f'N1_NUM[{i}]', description = 'N1 Numerator', - offset = ((0x030D+i) << 2), + offset = ((0x0D+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'N1_DEN[{i}]', description = 'N1 Denominator', - offset = ((0x0313+i) << 2), + offset = ((0x13+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N1_UPDATE", description = "Set this bit to update the N1 divider.", - offset = (0x0317 << 2), + offset = (0x17 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N2_NUM[{i}]', description = 'N2 Numerator', - offset = ((0x0318+i) << 2), + offset = ((0x18+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'N2_DEN[{i}]', description = 'N2 Denominator', - offset = ((0x031E+i) << 2), + offset = ((0x1E+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N2_UPDATE", description = "Set this bit to update the N2 divider.", - offset = (0x0322 << 2), + offset = (0x22 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N3_NUM[{i}]', description = 'N3 Numerator', - offset = ((0x0323+i) << 2), + offset = ((0x23+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'N3_DEN[{i}]', description = 'N3 Denominator', - offset = ((0x0329+i) << 2), + offset = ((0x29+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N3_UPDATE", description = "Set this bit to update the N3 divider.", - offset = (0x032D << 2), + offset = (0x2D << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N4_NUM[{i}]', description = 'N4 Numerator', - offset = ((0x032E+i) << 2), + offset = ((0x2E+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'N4_DEN[{i}]', description = 'N4 Denominator', - offset = ((0x0334+i) << 2), + offset = ((0x34+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N4_UPDATE", description = "Set this bit to update the N4 divider.", - offset = (0x0338 << 2), + offset = (0x38 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteCommand( name = "N_UPDATE_ALL", description = "Set this bit to update all five N dividers.", - offset = (0x0338 << 2), + offset = (0x38 << 2), bitSize = 1, bitOffset = 1, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'N_FSTEP_MSK', description = '0 to enable FINC/FDEC updates, 1 to disable FINC/FDEC updates', - offset = (0x0339 << 2), + offset = (0x39 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N0_FSTEPW[{i}]', description = 'N0 Frequency Step Word', - offset = ((0x033B+i) << 2), + offset = ((0x3B+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N1_FSTEPW[{i}]', description = 'N1 Frequency Step Word', - offset = ((0x0341+i) << 2), + offset = ((0x41+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N2_FSTEPW[{i}]', description = 'N2 Frequency Step Word', - offset = ((0x0347+i) << 2), + offset = ((0x47+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N3_FSTEPW[{i}]', description = 'N3 Frequency Step Word', - offset = ((0x034D+i) << 2), + offset = ((0x4D+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'N4_FSTEPW[{i}]', description = 'N4 Frequency Step Word', - offset = ((0x0353+i) << 2), + offset = ((0x53+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) class Si5345Page4(pr.Device): @@ -2087,17 +2275,18 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'ZDM_EN', description = '0 to disable ZD mode, 1 to enable ZD mode', - offset = (0x0487 << 2), + offset = (0x87 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'ZDM_IN_SEL', description = 'Clock input select when in ZD mode. Note: In ZD mode the feedback clock comes into IN3', - offset = (0x0487 << 2), + offset = (0x87 << 2), bitSize = 2, bitOffset = 1, mode = 'RW', @@ -2106,17 +2295,19 @@ def __init__(self, 0x1: 'IN1', 0x2: 'IN2', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'ZDM_AUTOSW_EN', description = 'Set by CBPro.', - offset = (0x0487 << 2), + offset = (0x87 << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) class Si5345Page5(pr.Device): @@ -2134,7 +2325,7 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'IN_ACTV', description = 'Currently selected DSPLL input clock', - offset = (0x0507 << 2), + offset = (0x07 << 2), bitSize = 2, bitOffset = 6, mode = 'RO', @@ -2144,90 +2335,99 @@ def __init__(self, 0x2: 'IN2', 0x3: 'IN3', }, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'BW_PLL[{i}]', description = 'PLL loop bandwidth parameter', - offset = ((0x0508+i) << 2), + offset = ((0x08+i) << 2), bitSize = 6, mode = 'RW', + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'FAST_LOCK_BW_PLL[{i}]', description = 'PLL Fast Lock Loop Bandwidth parameter', - offset = ((0x050E+i) << 2), + offset = ((0x0E+i) << 2), bitSize = 6, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "BW_UPDATE_PLL", description = "Must be set to 1 to update the BWx_PLL and FAST_BWx_PLL parameters", - offset = (0x0514 << 2), + offset = (0x14 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) for i in range(7): self.add(pr.RemoteVariable( name = f'M_NUM[{i}]', description = 'M Divider Numerator', - offset = ((0x0515+i) << 2), + offset = ((0x15+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) for i in range(4): self.add(pr.RemoteVariable( name = f'M_DEN[{i}]', description = 'M Divider Denominator', - offset = ((0x051C+i) << 2), + offset = ((0x1C+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteCommand( name = "M_UPDATE", description = "Set this bit to update the M divider.", - offset = (0x0520 << 2), + offset = (0x20 << 2), bitSize = 1, bitOffset = 0, # hidden = True, function = pr.BaseCommand.toggle, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'M_FRAC_MODE', description = 'M feedback divider fractional mode, Must be set to 0xB for proper operation', - offset = (0x0521 << 2), + offset = (0x21 << 2), bitSize = 4, bitOffset = 0, mode = 'WO', value = 0xB, hidden = True, verify = False, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'M_FRAC_EN', description = 'M feedback divider fractional enable: 0: Integer-only division, 1: Fractional (or integer) division - Required for DCO operation.', - offset = (0x0521 << 2), + offset = (0x21 << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'M_FRAC_RESERVED', description = 'Must be set to 1 for DSPLL B', - offset = (0x0521 << 2), + offset = (0x21 << 2), # base = pr.Bool, bitSize = 1, bitOffset = 5, @@ -2235,22 +2435,24 @@ def __init__(self, value = 0x1, hidden = True, verify = False, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_SEL_REGCTRL', description = '0 for pin controlled clock selection, 1 for register controlled clock selection', - offset = (0x052A << 2), + offset = (0x2A << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_SEL', description = 'Select DSPLL input clock', - offset = (0x052A << 2), + offset = (0x2A << 2), bitSize = 2, bitOffset = 1, mode = 'RW', @@ -2260,133 +2462,146 @@ def __init__(self, 0x2: 'IN2', 0x3: 'IN3', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_AUTO_EN', description = 'Applies only when FASTLOCK_MAN = 0 (see below): 0 to disable auto fast lock when the DSPLL is out of lock, 1 to enable auto fast lock', - offset = (0x052B << 2), + offset = (0x2B << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_MAN', description = '0 for normal operation (see FASTLOCK_AUTO_EN), 1 to force fast lock', - offset = (0x052B << 2), + offset = (0x2B << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_EN', description = 'Holdover enable: 0: Holdover Disabled, 1: Holdover Enabled (default)', - offset = (0x052C << 2), + offset = (0x2C << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_RAMP_BYP', description = 'HOLD_RAMP_BYP', - offset = (0x052C << 2), + offset = (0x2C << 2), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLDEXIT_BW_SEL1', description = 'Holdover Exit Bandwidth select', - offset = (0x052C << 2), + offset = (0x2C << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'RAMP_STEP_INTERVAL', description = 'Time Interval of the frequency ramp steps when ramping between inputs or when exiting holdover. Calculated by CBPro based on selection.', - offset = (0x052C << 2), + offset = (0x2C << 2), bitSize = 3, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_RAMPBYP_NOHIST', description = 'Set by CBPro.', - offset = (0x052D << 2), + offset = (0x2D << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_HIST_LEN', description = 'Set by CBPro.', - offset = (0x052E << 2), + offset = (0x2E << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_HIST_DELAY', description = 'Set by CBPro.', - offset = (0x052F << 2), + offset = (0x2F << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_REF_COUNT_FRC_PLLB', description = 'Set by CBPro.', - offset = (0x0531 << 2), + offset = (0x31 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(3): self.add(pr.RemoteVariable( name = f'HOLD_15M_CYC_COUNT_PLLB[{i}]', description = 'Value calculated by CBPro', - offset = ((0x0532+i) << 2), + offset = ((0x32+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FORCE_HOLD', description = '0 for normal operation, 1 for force holdover', - offset = (0x0535 << 2), + offset = (0x35 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'CLK_SWTCH_MODE', description = 'Clock switching mode', - offset = (0x0536 << 2), + offset = (0x36 << 2), bitSize = 2, bitOffset = 0, mode = 'RW', @@ -2395,40 +2610,44 @@ def __init__(self, 0x1: 'automatic_non-revertive', 0x2: 'automatic_revertive', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_EN', description = '0 glitchless switching mode (phase buildout turned off), 1 hitless switching mode (phase buildout turned on). Note: Hitless switching and zero delay mode are incompatible.', - offset = (0x0536 << 2), + offset = (0x36 << 2), base = pr.Bool, bitSize = 1, bitOffset = 2, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_LOS_MSK', description = 'For each clock input LOS alarm: 0 to use LOS in the clock selection logic, 1 to mask LOS from the clock selection logic', - offset = (0x0537 << 2), + offset = (0x37 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_OOF_MSK', description = 'For each clock input OOF alarm: 0 to use OOF in the clock selection logic, 1 to mask OOF from the clock selection logic', - offset = (0x0537 << 2), + offset = (0x37 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_PRIORITY[0]', description = 'priority for clock input', - offset = (0x0538 << 2), + offset = (0x38 << 2), bitSize = 3, bitOffset = 0, mode = 'RW', @@ -2439,12 +2658,13 @@ def __init__(self, 0x3: 'priority 3', 0x4: 'priority 4', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_PRIORITY[1]', description = 'priority for clock input', - offset = (0x0538 << 2), + offset = (0x38 << 2), bitSize = 3, bitOffset = 4, mode = 'RW', @@ -2455,12 +2675,13 @@ def __init__(self, 0x3: 'priority 3', 0x4: 'priority 4', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_PRIORITY[2]', description = 'priority for clock input', - offset = (0x0539 << 2), + offset = (0x39 << 2), bitSize = 3, bitOffset = 0, mode = 'RW', @@ -2471,12 +2692,13 @@ def __init__(self, 0x3: 'priority 3', 0x4: 'priority 4', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_PRIORITY[3]', description = 'priority for clock input', - offset = (0x0539 << 2), + offset = (0x39 << 2), bitSize = 3, bitOffset = 4, mode = 'RW', @@ -2487,184 +2709,202 @@ def __init__(self, 0x3: 'priority 3', 0x4: 'priority 4', }, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_MODE', description = '2: Default setting, do not modify', - offset = (0x053A << 2), + offset = (0x3A << 2), bitSize = 2, bitOffset = 0, mode = 'WO', value = 0x2, hidden = True, verify = False, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_PHMEAS_CTRL', description = '0: Default setting, do not modify', - offset = (0x053A << 2), + offset = (0x3A << 2), bitSize = 2, bitOffset = 2, mode = 'WO', value = 0x0, hidden = True, verify = False, + overlapEn = True, )) for i in range(2): self.add(pr.RemoteVariable( name = f'HSW_PHMEAS_THR[{i}]', description = '10-bit value. Set by CBPro.', - offset = ((0x053B+i) << 2), + offset = ((0x3B+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_COARSE_PM_LEN', description = 'Set by CBPro.', - offset = (0x053D << 2), + offset = (0x3D << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_COARSE_PM_DLY', description = 'Set by CBPro.', - offset = (0x053E << 2), + offset = (0x3E << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_HIST_VALID', description = '1 = there is enough historical frequency data collected for valid holdover', - offset = (0x053F << 2), + offset = (0x3F << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FASTLOCK_STATUS', description = '1 = PLL is in Fast Lock operation', - offset = (0x053F << 2), + offset = (0x3F << 2), base = pr.Bool, bitSize = 1, bitOffset = 2, mode = 'RO', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HSW_FINE_PM_LEN', description = 'Set by CBPro.', - offset = (0x0588 << 2), + offset = (0x88 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(2): self.add(pr.RemoteVariable( name = f'PFD_EN_DELAY[{i}]', description = 'Set by CBPro.', - offset = ((0x0589+i) << 2), + offset = ((0x89+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'INIT_LP_CLOSE_HO', description = '1: ramp on initial lock, 0: no ramp on initial lock', - offset = (0x059B << 2), + offset = (0x9B << 2), base = pr.Bool, bitSize = 1, bitOffset = 1, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_PRESERVE_HIST', description = 'Set by CBPro.', - offset = (0x059B << 2), + offset = (0x9B << 2), base = pr.Bool, bitSize = 1, bitOffset = 4, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_FRZ_WITH_INTONLY', description = 'Set by CBPro.', - offset = (0x059B << 2), + offset = (0x9B << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_EXIT_BW_SEL0', description = 'Set by CBPro.', - offset = (0x059B << 2), + offset = (0x9B << 2), base = pr.Bool, bitSize = 1, bitOffset = 6, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'HOLD_EXIT_STD_BO', description = 'Set by CBPro.', - offset = (0x059B << 2), + offset = (0x9B << 2), base = pr.Bool, bitSize = 1, bitOffset = 7, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(6): self.add(pr.RemoteVariable( name = f'HOLDEXIT_BW[{i}]', description = 'Set by CBPro.', - offset = ((0x059D+i) << 2), + offset = ((0x9D+i) << 2), bitSize = 6, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'RAMP_STEP_SIZE', description = 'Set by CBPro.', - offset = (0x05A6 << 2), + offset = (0xA6 << 2), bitSize = 3, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'RAMP_SWITCH_EN', description = 'Ramp Switching Enable: 0: Disable Ramp Switching, 1: Enable Ramp Switching (default)', - offset = (0x05A6 << 2), + offset = (0xA6 << 2), base = pr.Bool, bitSize = 1, bitOffset = 3, mode = 'RW', + overlapEn = True, )) class Si5345Page9(pr.Device): @@ -2682,70 +2922,77 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'XAXB_EXTCLK_EN', description = '0 to use a crystal at the XAXB pins, 1 to use an external clock source at the XAXB pins', - offset = (0x090E << 2), + offset = (0x0E << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IO_VDD_SEL', description = '0 for 1.8 V external connections, 1 for 3.3 V external connections', - offset = (0x0943 << 2), + offset = (0x43 << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_EN', description = '0: Disable and Powerdown Input Buffer, 1: Enable Input Buffer for IN3IN0.', - offset = (0x0949 << 2), + offset = (0x49 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'IN_PULSED_CMOS_EN', description = '0: Standard Input Format, 1: Pulsed CMOS Input Format for IN3IN0', - offset = (0x0949 << 2), + offset = (0x49 << 2), bitSize = 4, bitOffset = 4, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'INX_TO_PFD_EN', description = 'Value calculated in CBPro', - offset = (0x094A << 2), + offset = (0x4A << 2), bitSize = 4, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) for i in range(2): self.add(pr.RemoteVariable( name = f'REFCLK_HYS_SEL[{i}]', description = 'Value calculated in CBPro', - offset = ((0x094E+i) << 2), + offset = ((0x4E+i) << 2), bitSize = 8, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'MXAXB_INTEGER', description = 'Set by CBPro.', - offset = (0x095E << 2), + offset = (0x5E << 2), base = pr.Bool, bitSize = 1, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) class Si5345PageA(pr.Device): @@ -2762,48 +3009,53 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'N_ADD_0P5', description = 'Value calculated in CBPro.', - offset = (0x0A02 << 2), + offset = (0x02 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'N_CLK_TO_OUTX_EN', description = 'Routes Multisynth outputs to output driver muxes.', - offset = (0x0A03 << 2), + offset = (0x03 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'N_PIBYP', description = 'Output Multisynth integer divide mode: 0: Nx divider is fractional, 1: Nx divider is integer', - offset = (0x0A04 << 2), + offset = (0x04 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'N_PDNB', description = 'Powers down the N dividers, Set to 0 to power down unused N dividers, Must set to 1 for all active N dividers', - offset = (0x0A05 << 2), + offset = (0x05 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(5): self.add(pr.RemoteVariable( name = f'N_HIGH_FREQ[{i}]', description = 'Set by CBPro.', - offset = ((0x0A14+i) << 2), + offset = ((0x14+i) << 2), bitSize = 3, mode = 'RW', hidden = simpleDisplay, + overlapEn = True, )) class Si5345PageB(pr.Device): @@ -2821,64 +3073,71 @@ def __init__(self, self.add(pr.RemoteVariable( name = 'PDIV_FRACN_CLK_DIS_PLL', description = 'Disable digital clocks to input P (IN03) fractional dividers.', - offset = (0x0B44 << 2), + offset = (0x44 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'FRACN_CLK_DIS_PLL', description = 'Disable digital clock to M fractional divider.', - offset = (0x0B44 << 2), + offset = (0x44 << 2), base = pr.Bool, bitSize = 1, bitOffset = 5, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'LOS_CLK_DIS', description = 'Set to 0 for normal operation.', - offset = (0x0B46 << 2), + offset = (0x46 << 2), bitSize = 4, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_CLK_DIS', description = 'Set to 0 for normal operation.', - offset = (0x0B47 << 2), + offset = (0x47 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'OOF_DIV_CLK_DIS', description = 'Set to 0 for normal operation.', - offset = (0x0B48 << 2), + offset = (0x48 << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) self.add(pr.RemoteVariable( name = 'N_CLK_DIS', description = 'Disable digital clocks to N dividers. Must be set to 0 to use each N divider. See also related registers 0x0A03 and 0x0A05.', - offset = (0x0B4A << 2), + offset = (0x4A << 2), bitSize = 5, bitOffset = 0, mode = 'RW', + overlapEn = True, )) for i in range(2): self.add(pr.RemoteVariable( name = f'VCO_RESET_CALCODE[{i}]', description = '12-bit value. Controls the VCO frequency when a reset occurs.', - offset = ((0x0B57+i) << 2), + offset = ((0x57+i) << 2), bitSize = 8, mode = 'RW', + overlapEn = True, )) \ No newline at end of file From 7f6497c23f3a56b70f5c1fc1230b3c1a1788c514 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 09:00:49 -0700 Subject: [PATCH 43/92] integrating UART modules into _ClinkChannel.py --- python/surf/protocols/clink/_ClinkChannel.py | 51 +++++++++++--------- python/surf/protocols/clink/_ClinkTop.py | 21 +++++--- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 32edcd8dcc..1b430e7df7 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -17,14 +17,15 @@ # contained in the LICENSE.txt file. #----------------------------------------------------------------------------- -import pyrogue as pr -import surf.protocols.clink +import pyrogue as pr +import surf.protocols.clink as cl class ClinkChannel(pr.Device): def __init__( self, name = "ClinkChannel", description = "CameraLink channel", serial = None, + camType = None, **kwargs): super().__init__(name=name, description=description, **kwargs) @@ -186,31 +187,37 @@ def __init__( self, mode = "RO", pollInterval = 1, )) + + ############################################################################## self._rx = None self._tx = None + # Check if serial interface defined if serial is not None: - self._rx = surf.protocols.clink.ClinkSerialRx() - pr.streamConnect(serial,self._rx) - - self._tx = surf.protocols.clink.ClinkSerialTx() - pr.streamConnect(self._tx,serial) - - @self.command(value='', name='SendString', description='Send a command string') - def sendString(arg): - if self._tx is not None: - self._tx.sendString(arg) - - @self.command(name='SendEscape', description='Send an escape charactor') - def sendEscape(): - if self._tx is not None: - self._tx.sendEscape() - - @self.command(name='SendGcp', description='Send gcp command') - def sendGcp(): - if self._tx is not None: - self._tx.sendString("gcp") + # Check for OPA1000 camera + if (camType=='Opal000'): + self.add(cl.UartOpal000( + name = 'UartOpal000', + serial = serial, + expand = False, + )) + # Check for Piranha4 camera + elif (camType=='Piranha4'): + self.add(cl.UartPiranha4( + name = 'UartPiranha4', + serial = serial, + expand = False, + )) + # Else development interface to serial stream + else: + self._rx = cl.ClinkSerialRx() + pr.streamConnect(serial,self._rx) + self._tx = cl.ClinkSerialTx() + pr.streamConnect(self._tx,serial) + else: + raise ValueError(f'serial not defined' ) + ############################################################################## def hardReset(self): self.CntRst() diff --git a/python/surf/protocols/clink/_ClinkTop.py b/python/surf/protocols/clink/_ClinkTop.py index 2dda1fe329..d356210654 100644 --- a/python/surf/protocols/clink/_ClinkTop.py +++ b/python/surf/protocols/clink/_ClinkTop.py @@ -17,15 +17,15 @@ # contained in the LICENSE.txt file. #----------------------------------------------------------------------------- -import pyrogue as pr -import surf.protocols.clink +import pyrogue as pr +import surf.protocols.clink as cl class ClinkTop(pr.Device): def __init__( self, name = "ClinkTop", description = "CameraLink module", - serialA = None, - serialB = None, + serial = [None,None], + camType = [None,None], **kwargs): super().__init__(name=name, description=description, **kwargs) @@ -195,9 +195,16 @@ def __init__( self, pollInterval = 1, )) - self.add(surf.protocols.clink.ClinkChannel( name = "Channel[0]", serial=serialA, offset=0x100)) - self.add(surf.protocols.clink.ClinkChannel( name = "Channel[1]", serial=serialB, offset=0x200)) - + for i in range(2): + if serial[i] is not None: + self.add(cl.ClinkChannel( + name = f'Ch[{i}]', + offset = 0x100+(i*0x100), + serial = serial[i], + camType = camType[i], + # expand = False, + )) + def hardReset(self): self.CntRst() From 5323c17d212d957c83a1c0a61bd2185ea773c08c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 12:34:58 -0700 Subject: [PATCH 44/92] bug fix --- python/surf/protocols/pgp/_Pgp2bAxi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/surf/protocols/pgp/_Pgp2bAxi.py b/python/surf/protocols/pgp/_Pgp2bAxi.py index b56218d76b..1f1664dd36 100644 --- a/python/surf/protocols/pgp/_Pgp2bAxi.py +++ b/python/surf/protocols/pgp/_Pgp2bAxi.py @@ -373,7 +373,8 @@ def softReset(self): self.Flush() def hardReset(self): - self.ResetTxRx() + self.ResetTx() + self.ResetRx() def countReset(self): self.CountReset() From 34d86467c20d214dcb5a51c7804646a927a23e9f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 12:39:56 -0700 Subject: [PATCH 45/92] check writeEn before hardReset commands --- python/surf/protocols/pgp/_Pgp2bAxi.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/surf/protocols/pgp/_Pgp2bAxi.py b/python/surf/protocols/pgp/_Pgp2bAxi.py index 1f1664dd36..15b6ff212c 100644 --- a/python/surf/protocols/pgp/_Pgp2bAxi.py +++ b/python/surf/protocols/pgp/_Pgp2bAxi.py @@ -373,8 +373,9 @@ def softReset(self): self.Flush() def hardReset(self): - self.ResetTx() - self.ResetRx() + if self.writeEn: + self.ResetTx() + self.ResetRx() def countReset(self): self.CountReset() From e60442cc303a02e9b085f61eb86dcc8d5689da88 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 14:10:17 -0700 Subject: [PATCH 46/92] adding back sendString() command --- python/surf/protocols/clink/_ClinkChannel.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 1b430e7df7..805fb2cd52 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -219,6 +219,11 @@ def __init__( self, raise ValueError(f'serial not defined' ) ############################################################################## + @self.command(value='', name='SendString', description='Send a command string') + def sendString(arg): + if self._tx is not None: + self._tx.sendString(arg) + def hardReset(self): self.CntRst() From 9244beb28db4c36cb2172155f192114a337e7a77 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 14:10:50 -0700 Subject: [PATCH 47/92] prevent retry if lock already established --- protocols/clink/hdl/ClinkData.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/clink/hdl/ClinkData.vhd b/protocols/clink/hdl/ClinkData.vhd index 024ab1c0b8..6ad571567e 100644 --- a/protocols/clink/hdl/ClinkData.vhd +++ b/protocols/clink/hdl/ClinkData.vhd @@ -201,7 +201,7 @@ begin if r.count = 0 then if parClock = "1100011" and r.delay /= 31 then v.status.locked := '1'; - else + elsif (r.status.locked = '0') then -- Retry to lock again v := REG_INIT_C; end if; From 9067b29212dbe68c6c71aae2047b3d2e7848c5f3 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 14:30:56 -0700 Subject: [PATCH 48/92] adding clink/_UartGeneric.py --- python/surf/protocols/clink/_ClinkChannel.py | 22 +- python/surf/protocols/clink/_UartGeneric.py | 45 ++ python/surf/protocols/clink/_UartOpal000.py | 376 ++++++----- python/surf/protocols/clink/_UartPiranha4.py | 676 ++++++++++--------- python/surf/protocols/clink/__init__.py | 1 + 5 files changed, 582 insertions(+), 538 deletions(-) create mode 100644 python/surf/protocols/clink/_UartGeneric.py diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 805fb2cd52..603662146d 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -201,28 +201,22 @@ def __init__( self, name = 'UartOpal000', serial = serial, expand = False, - )) + )) # Check for Piranha4 camera elif (camType=='Piranha4'): self.add(cl.UartPiranha4( name = 'UartPiranha4', serial = serial, expand = False, - )) - # Else development interface to serial stream + )) + # Else generic interface to serial stream else: - self._rx = cl.ClinkSerialRx() - pr.streamConnect(serial,self._rx) - self._tx = cl.ClinkSerialTx() - pr.streamConnect(self._tx,serial) - else: - raise ValueError(f'serial not defined' ) + self.add(cl.UartGeneric( + name = 'UartGeneric', + serial = serial, + expand = False, + )) ############################################################################## - - @self.command(value='', name='SendString', description='Send a command string') - def sendString(arg): - if self._tx is not None: - self._tx.sendString(arg) def hardReset(self): self.CntRst() diff --git a/python/surf/protocols/clink/_UartGeneric.py b/python/surf/protocols/clink/_UartGeneric.py new file mode 100644 index 0000000000..db77c5221b --- /dev/null +++ b/python/surf/protocols/clink/_UartGeneric.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# Title : PyRogue CameraLink module +#----------------------------------------------------------------------------- +# File : UartGeneric.py +# Created : 2017-11-21 +#----------------------------------------------------------------------------- +# Description: +# PyRogue CameraLink module +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr +import rogue.interfaces.stream + +import surf.protocols.clink as clink + +class UartGeneric(pr.Device): + def __init__( self, + name = 'UartGeneric', + description = 'Uart Generic channel access', + serial = None, + **kwargs): + super().__init__(name=name, description=description, **kwargs) + + if serial is not None: + + # Attach the serial devices + self._rx = clink.ClinkSerialRx() + pr.streamConnect(serial,self._rx) + + self._tx = clink.ClinkSerialTx() + pr.streamConnect(self._tx,serial) + + @self.command(value='', name='SendString', description='Send a command string') + def sendString(arg): + if self._tx is not None: + self._tx.sendString(arg) diff --git a/python/surf/protocols/clink/_UartOpal000.py b/python/surf/protocols/clink/_UartOpal000.py index 51f0bef691..d37e1f276c 100644 --- a/python/surf/protocols/clink/_UartOpal000.py +++ b/python/surf/protocols/clink/_UartOpal000.py @@ -52,208 +52,210 @@ def __init__( self, serial = None, **kwargs): super().__init__(name=name, description=description, **kwargs) + + # Attach the serial devices + self._rx = UartOpal000Rx() + pr.streamConnect(serial,self._rx) - if serial is not None: + self._tx = clink.ClinkSerialTx() + pr.streamConnect(self._tx,serial) - # Attach the serial devices - self._rx = UartOpal000Rx() - pr.streamConnect(serial,self._rx) + @self.command(value='', name='SendString', description='Send a command string') + def sendString(arg): + if self._tx is not None: + self._tx.sendString(arg) - self._tx = clink.ClinkSerialTx() - pr.streamConnect(self._tx,serial) + ############################## + # Variables + ############################## + + self.add(pr.LocalVariable( + name = 'CCE[0]', + description = 'Selects the exposure control source and event selection', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' + )) - ############################## - # Variables - ############################## - - self.add(pr.LocalVariable( - name = 'CCE[0]', - description = 'Selects the exposure control source and event selection', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'CCE[1]', + description = 'Selects the exposure control source and event selection', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'CCFS[0]', + description = 'Selects the frame start control source and event selection', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' + )) - self.add(pr.LocalVariable( - name = 'CCE[1]', - description = 'Selects the exposure control source and event selection', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@CCE{self.CCE[0].get()};{self.CCE[1].get()}') if (self.CCE[0].get()!='' and self.CCE[1].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'CCFS[0]', - description = 'Selects the frame start control source and event selection', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'CCFS[1]', + description = 'Selects the frame start control source and event selection', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'DPE', + description = 'Enables or disables the defect pixel correction.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@DPE{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'CCFS[1]', - description = 'Selects the frame start control source and event selection', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@CCFS{self.CCFS[0].get()};{self.CCFS[1].get()}') if (self.CCFS[0].get()!='' and self.CCFS[1].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'DPE', - description = 'Enables or disables the defect pixel correction.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@DPE{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'FP', + description = 'Sets the frame period.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@FP{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'FP', - description = 'Sets the frame period.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@FP{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'FSM', + description = 'Selects the FSTROBE output and polarity', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@FSM{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'FST[0]', + description = 'Configures the FSTROBE, step, delay and active', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' + )) - self.add(pr.LocalVariable( - name = 'FSM', - description = 'Selects the FSTROBE output and polarity', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@FSM{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'FST[0]', - description = 'Configures the FSTROBE, step, delay and active', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'FST[1]', + description = 'Configures the FSTROBE, step, delay and active', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'GA', + description = 'Sets the digital gain of the camera.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@GA{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'IT', + description = 'Sets the integration time.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@IT{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'FST[1]', - description = 'Configures the FSTROBE, step, delay and active', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@FST{self.FST[0].get()};{self.FST[1].get()}') if (self.FST[0].get()!='' and self.FST[1].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'GA', - description = 'Sets the digital gain of the camera.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@GA{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'IT', - description = 'Sets the integration time.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@IT{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'MI', + description = 'Enables or disables the mirror function.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@MI{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'MO', + description = 'Sets the operating mode of the camera.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@MO{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'MI', - description = 'Enables or disables the mirror function.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@MI{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'MO', - description = 'Sets the operating mode of the camera.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@MO{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'OFS', + description = 'Sets the output offset in GL at 12 bit internal resolution', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@OFS{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'OFS', - description = 'Sets the output offset in GL at 12 bit internal resolution', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@OFS{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'OR', + description = 'Sets the output resolution of the camera.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@OR{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'TP', + description = 'Selects display of the test pattern', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@TP{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'OR', - description = 'Sets the output resolution of the camera.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@OR{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'TP', - description = 'Selects display of the test pattern', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@TP{value}') if value!='' else '' - )) + self.add(pr.LocalVariable( + name = 'VBIN', + description = 'Sets the image output binning', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@VBIN{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'WB[0]', + description = 'Sets the gain for the Red, Green and Blue channel', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + )) - self.add(pr.LocalVariable( - name = 'VBIN', - description = 'Sets the image output binning', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@VBIN{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'WB[0]', - description = 'Sets the gain for the Red, Green and Blue channel', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'WB[1]', + description = 'Sets the gain for the Red, Green and Blue channel', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + )) - self.add(pr.LocalVariable( - name = 'WB[1]', - description = 'Sets the gain for the Red, Green and Blue channel', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'WB[2]', + description = 'Sets the gain for the Red, Green and Blue channel', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'BL', + description = 'Sets the black level.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@BL{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'VR', + description = 'Enableling and disableling the vertical remap is done by means of the vertical remap command.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@VR{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'WB[2]', - description = 'Sets the gain for the Red, Green and Blue channel', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@WB{self.WB[0].get()};{self.WB[1].get()};{self.WB[2].get()}') if (self.WB[0].get()!='' and self.WB[1].get()!='' and self.WB[2].get()!='') else '' - )) + self.add(pr.LocalVariable( + name = 'FSP', + description = ''' + The active state of the strobe output can be inverted to adapt to the application requirements. + 0 for the reverse polarity: in this polarity configuration the phototransistor at the camera output is non-conductive during the active state of the strobe. + 1 for the normal polarity: in this polarity configuration the phototransistor at the camera output is conductive during the active state of the strobe. + ''', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'@FSP{value}') if value!='' else '' + )) - self.add(pr.LocalVariable( - name = 'BL', - description = 'Sets the black level.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@BL{value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'VR', - description = 'Enableling and disableling the vertical remap is done by means of the vertical remap command.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@VR{value}') if value!='' else '' - )) - self.add(pr.LocalVariable( - name = 'FSP', - description = ''' - The active state of the strobe output can be inverted to adapt to the application requirements. - 0 for the reverse polarity: in this polarity configuration the phototransistor at the camera output is non-conductive during the active state of the strobe. - 1 for the normal polarity: in this polarity configuration the phototransistor at the camera output is conductive during the active state of the strobe. - ''', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'@FSP{value}') if value!='' else '' - )) - - else: - raise ValueError('UartOpal000.serial=none (no streaming interface attached)' ) \ No newline at end of file diff --git a/python/surf/protocols/clink/_UartPiranha4.py b/python/surf/protocols/clink/_UartPiranha4.py index 103ccb18ad..e064f320a6 100644 --- a/python/surf/protocols/clink/_UartPiranha4.py +++ b/python/surf/protocols/clink/_UartPiranha4.py @@ -30,341 +30,343 @@ def __init__( self, **kwargs): super().__init__(name=name, description=description, **kwargs) - if serial is not None: + # Attach the serial devices + self._rx = clink.ClinkSerialRx() + pr.streamConnect(serial,self._rx) + + self._tx = clink.ClinkSerialTx() + pr.streamConnect(self._tx,serial) + + @self.command(value='', name='SendString', description='Send a command string') + def sendString(arg): + if self._tx is not None: + self._tx.sendString(arg) + + ############################## + # Variables + ############################## + + self.add(pr.LocalVariable( + name = 'CCF', + description = 'Calibrate user FPN dark flat field coefficients', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ccf {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CLS', + description = 'Camera Link clock frequency', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cls {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CLM', + description = 'Camera Link Mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'clm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[0]', + description = 'Calibrate user PRNU flat field coefficients: Algorithm Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[1]', + description = 'Calibrate user PRNU flat field coefficients: \# of lines to average Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'CPA[2]', + description = 'Calibrate user PRNU flat field coefficients: Target Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'DST', + description = 'Use this command to switch between Area and Single Line modes.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'dst {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'FFM', + description = 'Set flat field mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ffm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'FRS', + description = 'Set scan direction controlled reverse set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'GCP', + description = 'Display current value of camera configuration parameters', + function = lambda cmd: self._tx.sendString('gcp') + )) + + self.add(pr.LocalVariable( + name = 'GET', + description = 'The /"get/" command displays the current value(s) of the feature specified in the string parameter. Note that the parameter is preceded by a single quote \"\". Using this command will be easier for control software than parsing the output from the \"gcp\" command.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'get {value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'H', + description = 'Display list of three letter commands', + function = lambda cmd: self._tx.sendString('h') + )) + + self.add(pr.LocalVariable( + name = 'LPC', + description = 'Load user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'lpc {value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'RC', + description = 'Resets the camera to the saved user default settings. These settings are saved using the usd command.', + function = lambda cmd: self._tx.sendString('rc') + )) + + self.add(pr.LocalVariable( + name = 'ROI[0]', + description = 'Flat field region of interest: First pixel Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'ROI[1]', + description = 'Flat field region of interest: Last pixel Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' + )) + + self.add(pr.BaseCommand( + name = 'RPC', + description = 'Reset all user FPN values to zero and all user PRNU coefficients to one', + function = lambda cmd: self._tx.sendString('rpc') + )) + + self.add(pr.LocalVariable( + name = 'SAC', + description = 'Set AOI Counter', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sac {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[0]', + description = 'Define an AOI: Selector Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[1]', + description = 'Define an AOI: Offset Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAD[2]', + description = 'Define an AOI: Width Argument', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' + )) + + self.add(pr.LocalVariable( + name = 'SAM', + description = 'Set AOI mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sam {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SBH', + description = 'Set horizontal binning', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sbh {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SBR', + description = 'Set baud rate', + mode = 'RW', + value = '', + units = 'bps', + localSet = lambda value: self._tx.sendString(f'sbr {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SBV', + description = 'Set vertical binning', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sbv {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SCD', + description = 'Set sensor scan direction', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'scd {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SEM', + description = 'Set exposure time mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sem {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SET', + description = 'Set internal exposure time in nanoseconds (25 ns resolution)', + mode = 'RW', + value = '', + units = '25ns', + localSet = lambda value: self._tx.sendString(f'set {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SMM', + description = 'Set mirroring mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'smm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SPF', + description = 'Set pixel format', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'spf {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SSB', + description = 'Set contrast offset - single value added to all pixels after PRNU/flat field coefficients (before gain).', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ssb {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SSF', + description = 'Set internal line rate in Hz', + mode = 'RW', + value = '', + units = 'Hz', + localSet = lambda value: self._tx.sendString(f'ssf {value}') if value!='' else '' + )) - # Attach the serial devices - self._rx = clink.ClinkSerialRx() - pr.streamConnect(serial,self._rx) - - self._tx = clink.ClinkSerialTx() - pr.streamConnect(self._tx,serial) - - ############################## - # Variables - ############################## - - self.add(pr.LocalVariable( - name = 'CCF', - description = 'Calibrate user FPN dark flat field coefficients', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'ccf {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'CLS', - description = 'Camera Link clock frequency', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'cls {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'CLM', - description = 'Camera Link Mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'clm {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'CPA[0]', - description = 'Calibrate user PRNU flat field coefficients: Algorithm Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'CPA[1]', - description = 'Calibrate user PRNU flat field coefficients: \# of lines to average Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'CPA[2]', - description = 'Calibrate user PRNU flat field coefficients: Target Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'cpa {self.CPA[0].get()} {self.CPA[1].get()} {self.CPA[2].get()}') if (self.CPA[0].get()!='' and self.CPA[1].get()!='' and self.CPA[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'DST', - description = 'Use this command to switch between Area and Single Line modes.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'dst {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'FFM', - description = 'Set flat field mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'ffm {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'FRS', - description = 'Set scan direction controlled reverse set', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'frs {value}') if value!='' else '' - )) - - self.add(pr.BaseCommand( - name = 'GCP', - description = 'Display current value of camera configuration parameters', - function = lambda cmd: self._tx.sendString('gcp') - )) - - self.add(pr.LocalVariable( - name = 'GET', - description = 'The /"get/" command displays the current value(s) of the feature specified in the string parameter. Note that the parameter is preceded by a single quote \"\". Using this command will be easier for control software than parsing the output from the \"gcp\" command.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'get {value}') if value!='' else '' - )) - - self.add(pr.BaseCommand( - name = 'H', - description = 'Display list of three letter commands', - function = lambda cmd: self._tx.sendString('h') - )) - - self.add(pr.LocalVariable( - name = 'LPC', - description = 'Load user set', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'lpc {value}') if value!='' else '' - )) - - self.add(pr.BaseCommand( - name = 'RC', - description = 'Resets the camera to the saved user default settings. These settings are saved using the usd command.', - function = lambda cmd: self._tx.sendString('rc') - )) - - self.add(pr.LocalVariable( - name = 'ROI[0]', - description = 'Flat field region of interest: First pixel Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'ROI[1]', - description = 'Flat field region of interest: Last pixel Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'roi {self.ROI[0].get()} {self.ROI[1].get()}') if (self.ROI[0].get()!='' and self.ROI[1].get()!='') else '' - )) - - self.add(pr.BaseCommand( - name = 'RPC', - description = 'Reset all user FPN values to zero and all user PRNU coefficients to one', - function = lambda cmd: self._tx.sendString('rpc') - )) - - self.add(pr.LocalVariable( - name = 'SAC', - description = 'Set AOI Counter', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sac {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SAD[0]', - description = 'Define an AOI: Selector Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'SAD[1]', - description = 'Define an AOI: Offset Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'SAD[2]', - description = 'Define an AOI: Width Argument', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sad {self.SAD[0].get()} {self.SAD[1].get()} {self.SAD[2].get()}') if (self.SAD[0].get()!='' and self.SAD[1].get()!='' and self.SAD[2].get()!='') else '' - )) - - self.add(pr.LocalVariable( - name = 'SAM', - description = 'Set AOI mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sam {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SBH', - description = 'Set horizontal binning', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sbh {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SBR', - description = 'Set baud rate', - mode = 'RW', - value = '', - units = 'bps', - localSet = lambda value: self._tx.sendString(f'sbr {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SBV', - description = 'Set vertical binning', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sbv {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SCD', - description = 'Set sensor scan direction', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'scd {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SEM', - description = 'Set exposure time mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'sem {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SET', - description = 'Set internal exposure time in nanoseconds (25 ns resolution)', - mode = 'RW', - value = '', - units = '25ns', - localSet = lambda value: self._tx.sendString(f'set {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SMM', - description = 'Set mirroring mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'smm {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SPF', - description = 'Set pixel format', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'spf {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SSB', - description = 'Set contrast offset - single value added to all pixels after PRNU/flat field coefficients (before gain).', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'ssb {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SSF', - description = 'Set internal line rate in Hz', - mode = 'RW', - value = '', - units = 'Hz', - localSet = lambda value: self._tx.sendString(f'ssf {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SSG', - description = 'Set gain as a single value multiplied by all pixels.', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'ssg {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'STG', - description = 'Set TDI Stages', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'stg {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'STM', - description = 'Set trigger mode', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'stm {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'SVM', - description = 'Select test pattern', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'svm {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'USD', - description = 'Select user set to load when camera is reset', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'usd {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'USL', - description = 'Load user set', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'usl {value}') if value!='' else '' - )) - - self.add(pr.LocalVariable( - name = 'USS', - description = 'Save user set', - mode = 'RW', - value = '', - localSet = lambda value: self._tx.sendString(f'uss {value}') if value!='' else '' - )) - - self.add(pr.BaseCommand( - name = 'VT', - description = 'Display internal temperature in degrees Celsius', - function = lambda cmd: self._tx.sendString('vt'), - )) - - self.add(pr.BaseCommand( - name = 'VV', - description = 'Display supply voltage', - function = lambda cmd: self._tx.sendString('vv'), - )) - - self.add(pr.BaseCommand( - name = 'SendEscape', - description = 'Send the Escape Char', - function = lambda cmd: self._tx.sendEscape() - )) - \ No newline at end of file + self.add(pr.LocalVariable( + name = 'SSG', + description = 'Set gain as a single value multiplied by all pixels.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ssg {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'STG', + description = 'Set TDI Stages', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'stg {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'STM', + description = 'Set trigger mode', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'stm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SVM', + description = 'Select test pattern', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'svm {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USD', + description = 'Select user set to load when camera is reset', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'usd {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USL', + description = 'Load user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'usl {value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'USS', + description = 'Save user set', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'uss {value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'VT', + description = 'Display internal temperature in degrees Celsius', + function = lambda cmd: self._tx.sendString('vt'), + )) + + self.add(pr.BaseCommand( + name = 'VV', + description = 'Display supply voltage', + function = lambda cmd: self._tx.sendString('vv'), + )) + + self.add(pr.BaseCommand( + name = 'SendEscape', + description = 'Send the Escape Char', + function = lambda cmd: self._tx.sendEscape() + )) diff --git a/python/surf/protocols/clink/__init__.py b/python/surf/protocols/clink/__init__.py index b365473ec1..84bfe033a8 100644 --- a/python/surf/protocols/clink/__init__.py +++ b/python/surf/protocols/clink/__init__.py @@ -15,5 +15,6 @@ from surf.protocols.clink._ClinkChannel import * # Library of support Camera UART interfaces +from surf.protocols.clink._UartGeneric import * from surf.protocols.clink._UartOpal000 import * from surf.protocols.clink._UartPiranha4 import * From cea84cf2bada34132a1b791d02889370837df088 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 25 Mar 2019 16:38:13 -0700 Subject: [PATCH 49/92] adding UartUp900cl12b.py --- python/surf/protocols/clink/_ClinkChannel.py | 9 +- .../surf/protocols/clink/_UartUp900cl12b.py | 156 ++++++++++++++++++ python/surf/protocols/clink/__init__.py | 7 +- 3 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 python/surf/protocols/clink/_UartUp900cl12b.py diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 603662146d..f7c62e6cdd 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -208,7 +208,14 @@ def __init__( self, name = 'UartPiranha4', serial = serial, expand = False, - )) + )) + # Check for Uniq UP-900CL-12B camera + elif (camType=='UartUp900cl12b'): + self.add(cl.UartPiranha4( + name = 'UartUp900cl12b', + serial = serial, + expand = False, + )) # Else generic interface to serial stream else: self.add(cl.UartGeneric( diff --git a/python/surf/protocols/clink/_UartUp900cl12b.py b/python/surf/protocols/clink/_UartUp900cl12b.py new file mode 100644 index 0000000000..0bdeef8121 --- /dev/null +++ b/python/surf/protocols/clink/_UartUp900cl12b.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# Title : PyRogue CameraLink module +#----------------------------------------------------------------------------- +# File : _UartUp900cl12b.py +# Created : 2017-11-21 +#----------------------------------------------------------------------------- +# Description: +# PyRogue CameraLink module +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr +import rogue.interfaces.stream + +import surf.protocols.clink as clink + +class UartUp900cl12b(pr.Device): + def __init__( self, + name = 'UartUp900cl12b', + description = 'Uart Uniq UP-900CL-12B channel access', + serial = None, + **kwargs): + super().__init__(name=name, description=description, **kwargs) + + # Attach the serial devices + self._rx = clink.ClinkSerialRx() + pr.streamConnect(serial,self._rx) + + self._tx = clink.ClinkSerialTx() + pr.streamConnect(self._tx,serial) + + @self.command(value='', name='SendString', description='Send a command string') + def sendString(arg): + if self._tx is not None: + self._tx.sendString(arg) + + ############################## + # Variables + ############################## + + self.add(pr.LocalVariable( + name = 'RU', + description = 'Recall user page: Must have a number after “ru” such as 1, 2, 3 or 4', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'ru{value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'RP', + description = 'Report current camera setting', + function = lambda cmd: self._tx.sendString('rp') + )) + + self.add(pr.BaseCommand( + name = 'RF', + description = 'Recall factory setting page', + function = lambda cmd: self._tx.sendString('rf') + )) + + self.add(pr.LocalVariable( + name = 'SM', + description = 'Shutter mode: Must have a number after sm (1 ~ f), refer to section 3.3 for details.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sm{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'SP', + description = 'Save user page: There are 4 user page available', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'sp{value}') if value!='' else '' + )) + + self.add(pr.BaseCommand( + name = 'NS', + description = 'Normal speed: Refer to camera specifications', + function = lambda cmd: self._tx.sendString('ns') + )) + + self.add(pr.BaseCommand( + name = 'DS', + description = 'Double speed: Refer to camera specifications', + function = lambda cmd: self._tx.sendString('ds') + )) + + self.add(pr.BaseCommand( + name = 'NM', + description = 'Normal mode: Normal free running', + function = lambda cmd: self._tx.sendString('nm') + )) + + self.add(pr.BaseCommand( + name = 'AM', + description = 'Asynchronous mode: Asynchronous reset', + function = lambda cmd: self._tx.sendString('nm') + )) + + self.add(pr.LocalVariable( + name = 'GI', + description = 'Gain increase: ### = Hexadecimals (000 ~ 3ff). If no number entered, gain will be increased by factor of 1. If a number is entered, then number will be added to stored gain.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'gi{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'GD', + description = 'Gain decrease: ### = Hexadecimals (000 ~ 3ff). Same as gi, except it will be decreased.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'gd{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'GN', + description = 'Gain number: ### = Hexadecimals (000 ~ 3ff). Refer to the gain curves below for details', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'gn{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'BI', + description = 'Reference increase: ### = Hexadecimals (000 ~ 3ff). If no number entered, reference will be increased by factor of 1. If a number is entered, then number will be added to stored reference. Note: It’s very uncommon to change reference level, contact UNIQ for further details.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'bi{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'BD', + description = 'Reference decrease: ### = Hexadecimals (000 ~ 3ff). If no number entered, reference will be increased by factor of 1. If a number is entered, then number will be added to stored reference. Note: It’s very uncommon to change reference level, contact UNIQ for further details.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'bd{value}') if value!='' else '' + )) + + self.add(pr.LocalVariable( + name = 'BN', + description = 'Reference number: ### = Hexadecimals (000 ~ 3ff). If no number entered, reference will be increased by factor of 1. If a number is entered, then number will be added to stored reference. Note: It’s very uncommon to change reference level, contact UNIQ for further details.', + mode = 'RW', + value = '', + localSet = lambda value: self._tx.sendString(f'bn{value}') if value!='' else '' + )) + \ No newline at end of file diff --git a/python/surf/protocols/clink/__init__.py b/python/surf/protocols/clink/__init__.py index 84bfe033a8..86a45453f2 100644 --- a/python/surf/protocols/clink/__init__.py +++ b/python/surf/protocols/clink/__init__.py @@ -15,6 +15,7 @@ from surf.protocols.clink._ClinkChannel import * # Library of support Camera UART interfaces -from surf.protocols.clink._UartGeneric import * -from surf.protocols.clink._UartOpal000 import * -from surf.protocols.clink._UartPiranha4 import * +from surf.protocols.clink._UartGeneric import * +from surf.protocols.clink._UartOpal000 import * +from surf.protocols.clink._UartPiranha4 import * +from surf.protocols.clink._UartUp900cl12b import * From 227fbe92b996016428d3329f087cb39d57e26274 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Mar 2019 09:53:22 -0700 Subject: [PATCH 50/92] Add Axi lite wrapper for batcher --- .../batcher/rtl/AxiStreamBatcherAxil.vhd | 152 ++++++++++++++++++ .../batcher/_AxiStreamBatcherAxil.py | 33 ++++ python/surf/protocols/batcher/__init__.py | 1 + 3 files changed, 186 insertions(+) create mode 100644 protocols/batcher/rtl/AxiStreamBatcherAxil.vhd create mode 100644 python/surf/protocols/batcher/_AxiStreamBatcherAxil.py create mode 100644 python/surf/protocols/batcher/__init__.py diff --git a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd new file mode 100644 index 0000000000..eda5ef7f1d --- /dev/null +++ b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd @@ -0,0 +1,152 @@ +------------------------------------------------------------------------------- +-- Title : AXI-Lite wrapper for AXI-Stream Batcher +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +-- Platform : +-- Standard : VHDL'93/02 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- This file is part of SURF. 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 SURF, 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; +use work.AxiStreamPkg.all; +use work.AxiLitePkg.all; + +entity AxiStreamBatcherAxil is + + generic ( + TPD_G : time := 1 ns; + COMMON_CLOCK_G : boolean := false; + MAX_NUMBER_SUB_FRAMES_G : positive := 32; + SUPER_FRAME_BYTE_THRESHOLD_G : natural := 8192; + MAX_CLK_GAP_G : natural := 256; + AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C; + INPUT_PIPE_STAGES_G : natural := 0; + OUTPUT_PIPE_STAGES_G : natural := 1); + + port ( + axisClk : in sl; + axisRst : in sl; + idle : out sl; + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType; + axilClk : in sl; + axilRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); + +end entity AxiStreamBatcherAxil; + +architecture rtl of AxiStreamBatcherAxil is + + type RegType is record + superFrameByteThreshold : slv(31 downto 0); + maxSubFrames : slv(15 downto 0); + maxClkGap : slv(11 downto 0); + axilReadSlave : AxiLiteReadSlaveType; + axilWriteSlave : AxiLiteWriteSlaveType; + end record RegType; + + constant REG_INIT_C : RegType := ( + superFrameByteThreshold => toSlv(SUPER_FRAME_BYTE_THRESHOLD_G, 32), + maxSubFrames => toSlv(MAX_NUMBER_SUB_FRAMES_G, 16), + maxClkGap => toSlv(MAX_CLK_GAP_G, 12), + axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, + axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal syncAxilReadMaster : AxiLiteReadMasterType; + signal syncAxilReadSlave : AxiLiteReadSlaveType; + signal syncAxilWriteMaster : AxiLiteWriteMasterType; + signal syncAxilWriteSlave : AxiLiteWriteSlaveType); + +begin + + U_AxiStreamBatcher_1 : entity work.AxiStreamBatcher + generic map ( + TPD_G => TPD_G, + MAX_NUMBER_SUB_FRAMES_G => MAX_NUMBER_SUB_FRAMES_G, + SUPER_FRAME_BYTE_THRESHOLD_G => SUPER_FRAME_BYTE_THRESHOLD_G, + MAX_CLK_GAP_G => MAX_CLK_GAP_G, + AXIS_CONFIG_G => AXIS_CONFIG_G, + INPUT_PIPE_STAGES_G => INPUT_PIPE_STAGES_G, + OUTPUT_PIPE_STAGES_G => OUTPUT_PIPE_STAGES_G) + port map ( + axisClk => axisClk, -- [in] + axisRst => axisRst, -- [in] + superFrameByteThreshold => r.superFrameByteThreshold, -- [in] + maxSubFrames => r.maxSubFrames, -- [in] + maxClkGap => r.maxClkGap, -- [in] + idle => idle, -- [out] + sAxisMaster => sAxisMaster, -- [in] + sAxisSlave => sAxisSlave, -- [out] + mAxisMaster => mAxisMaster, -- [out] + mAxisSlave => mAxisSlave); -- [in] + + U_AxiLiteAsync_1 : entity work.AxiLiteAsync + generic map ( + TPD_G => TPD_G, + COMMON_CLK_G => COMMON_CLOCK_G) + port map ( + sAxiClk => axilClk, -- [in] + sAxiClkRst => axilClk, -- [in] + sAxiReadMaster => axilReadMaster, -- [in] + sAxiReadSlave => axilReadSlave, -- [out] + sAxiWriteMaster => axilWriteMaster, -- [in] + sAxiWriteSlave => axilWriteSlave, -- [out] + mAxiClk => axisClk, -- [in] + mAxiClkRst => axisRst, -- [in] + mAxiReadMaster => syncAxilReadMaster, -- [out] + mAxiReadSlave => r.axilReadSlave, -- [in] + mAxiWriteMaster => syncAxilWriteMaster, -- [out] + mAxiWriteSlave => r.axilWriteSlave); -- [in] + + comb : process (r, syncAxilReadMaster, syncAxilWriteMaster) is + variable v : RegType; + variable axilEp : AxiLiteEndpointType; + begin + v := r; + + axiSlaveWaitTxn(axilEp, syncAxilWriteMaster, syncAxilReadMaster, v.axilWriteSlave, v.axilReadSlave); + + axiSlaveRegister(axilEp, X"00", 0, v.superFrameByteThreshold); + axiSlaveRegister(axilEp, X"04", 0, v.maxSubFrames); + axiSlaveRegister(axilEp, X"08", 0, v.maxClkGap); + + axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); + + rin <= v; + + if (v.axisRst) then + v := REG_INIT_C; + end if; + + end process comb; + + seq : process (axisClk) is + begin + if (rising_edge(axisClk)) then + r <= rin after TPD_G; + end if; + end process seq; + +end architecture rtl; + diff --git a/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py b/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py new file mode 100644 index 0000000000..da8181bb58 --- /dev/null +++ b/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py @@ -0,0 +1,33 @@ +import pyrogue as pr + +class AxiStreamBatcherAxil(pr.Device): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.add(pr.RemoteVariable( + name = 'SuperFrameByteThreshold', + offset = 0x00, + bitOffset = 0, + bitSize = 32, + mode = 'RW', + base = pr.UInt, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'MaxSubFrames', + offset = 0x04, + bitOffset = 0, + bitSize = 16, + mode = 'RW', + base = pr.UInt, + disp = '{:d}')) + + self.add(pr.RemoteVariable( + name = 'MaxClkGap', + offset = 0x08, + bitOffset = 0, + bitSize = 12, + mode = 'RW', + base = pr.UInt, + disp = '{:d}')) + diff --git a/python/surf/protocols/batcher/__init__.py b/python/surf/protocols/batcher/__init__.py new file mode 100644 index 0000000000..c1424fb8e1 --- /dev/null +++ b/python/surf/protocols/batcher/__init__.py @@ -0,0 +1 @@ +from surf.protocols.batcher._AxiStreamBatcherAxil import * From 66c28564a04af346c847fa54e254a136e011a396 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Mar 2019 10:26:36 -0700 Subject: [PATCH 51/92] Fix typos --- protocols/batcher/rtl/AxiStreamBatcherAxil.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd index eda5ef7f1d..676ce1c526 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd @@ -76,7 +76,7 @@ architecture rtl of AxiStreamBatcherAxil is signal syncAxilReadMaster : AxiLiteReadMasterType; signal syncAxilReadSlave : AxiLiteReadSlaveType; signal syncAxilWriteMaster : AxiLiteWriteMasterType; - signal syncAxilWriteSlave : AxiLiteWriteSlaveType); + signal syncAxilWriteSlave : AxiLiteWriteSlaveType; begin @@ -135,7 +135,7 @@ begin rin <= v; - if (v.axisRst) then + if (axisRst) then v := REG_INIT_C; end if; From 39add7c98b9c958b52c4695c1d180ca14ac10f7a Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Mar 2019 11:06:23 -0700 Subject: [PATCH 52/92] Fix typo --- protocols/batcher/rtl/AxiStreamBatcherAxil.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd index 676ce1c526..166e983525 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd @@ -135,7 +135,7 @@ begin rin <= v; - if (axisRst) then + if (axisRst = '1') then v := REG_INIT_C; end if; From d1173ee16ed39ef161fcd6153593687d7416b83b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Mar 2019 12:39:08 -0700 Subject: [PATCH 53/92] adding xilinx/_ClockManager.py --- python/surf/xilinx/_ClockManager.py | 538 ++++++++++++++++++++++++++++ python/surf/xilinx/__init__.py | 11 +- 2 files changed, 544 insertions(+), 5 deletions(-) create mode 100644 python/surf/xilinx/_ClockManager.py diff --git a/python/surf/xilinx/_ClockManager.py b/python/surf/xilinx/_ClockManager.py new file mode 100644 index 0000000000..136d26c5f0 --- /dev/null +++ b/python/surf/xilinx/_ClockManager.py @@ -0,0 +1,538 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# 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. +#----------------------------------------------------------------------------- + +import rogue +import pyrogue as pr + +class ClockManager(pr.Device): + def __init__( self, + name = "ClockManager", + description = "MMCM and PLL Dynamic Reconfiguration (refer to XAPP888: https://www.xilinx.com/support/documentation/application_notes/xapp888_7Series_DynamicRecon.pdf)", + type = None, # [MMCME2,PLLE2,MMCME3,PLLE3,MMCME4,PLLE4] + **kwargs): + super().__init__(name=name, description=description, **kwargs) + + # Determine the number of clkout + if (type is 'PLLE3') or (type is 'PLLE4'): + numClkOut = 2 + elif (type is 'PLLE2'): + numClkOut = 6 + elif (type is 'MMCME2') or (type is 'MMCME3') or (type is 'MMCME4'): + numClkOut = 7 + else: + raise ValueError('ClockManager: Invalid type (%s)' % (type) ) + + # Determine if UltraScale or not + UltraScale = False if (type is 'MMCME2') or (type is 'PLLE2') else True + + ############################################################################## + # ClkReg1 Bitmap for CLKOUT[6:0] + ############################################################################## + # CLKOUT0 Register 1 (Address=0x08) + # CLKOUT1 Register 1 (Address=0x0A) + # CLKOUT2 Register 1 (Address=0x0C): Not available for PLLE3 or PLLE4 + # CLKOUT3 Register 1 (Address=0x0E): Not available for PLLE3 or PLLE4 + # CLKOUT4 Register 1 (Address=0x10): Not available for PLLE3 or PLLE4 + # CLKOUT5 Register 1 (Address=0x06) + # CLKOUT6 Register 1 (Address=0x12): Not available for PLLE2, PLLE3, or PLLE4 + ClkReg1 = [0x08,0x0A,0x0C,0x0E,0x10,0x06,0x12] + + for i in range(numClkOut): + + if (type is not 'PLLE3') and (type is not 'PLLE4'): + self.add(pr.RemoteVariable( + name = f'PHASE_MUX[{i}]', + description = """ + Chooses an initial phase offset for the clock output, the + resolution is equal to 1/8 VCO period. Not available in + UltraScale PLLE3 and UltraScale+ PLLE4. + """, + offset = (ClkReg1[i] << 2), + bitSize = 3, + bitOffset = 13, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = f'HIGH_TIME[{i}]', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains High. + """, + offset = (ClkReg1[i] << 2), + bitSize = 6, + bitOffset = 6, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = f'LOW_TIME[{i}]', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains Low. + """, + offset = (ClkReg1[i] << 2), + bitSize = 6, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # CLKFBOUT Register 1 (Address=0x14) + ############################################################################## + + if (type is not 'PLLE3') and (type is not 'PLLE4'): + self.add(pr.RemoteVariable( + name = 'PHASE_MUX_FB', + description = """ + Chooses an initial phase offset for the clock output, the + resolution is equal to 1/8 VCO period. Not available in + UltraScale PLLE3 and UltraScale+ PLLE4. + """, + offset = (0x14 << 2), + bitSize = 3, + bitOffset = 13, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'HIGH_TIME_FB', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains High. + """, + offset = (0x14 << 2), + bitSize = 6, + bitOffset = 6, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'LOW_TIME_FB', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains Low. + """, + offset = (0x14 << 2), + bitSize = 6, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # ClkReg2 Bitmap for CLKOUT[6:0] + ############################################################################## + # CLKOUT0 Register 2 (Address=0x09) + # CLKOUT1 Register 2 (Address=0x0B) + # CLKOUT2 Register 2 (Address=0x0D): Not available for PLLE3 or PLLE4 + # CLKOUT3 Register 2 (Address=0x0F): Not available for PLLE3 or PLLE4 + # CLKOUT4 Register 2 (Address=0x11): Not available for PLLE3 or PLLE4 + # CLKOUT5 Register 2 (Address=0x07) + # CLKOUT6 Register 2 (Address=0x13): Not available for PLLE2, PLLE3, or PLLE4 + ClkReg2 = [0x09,0x0B,0x0D,0x0F,0x11,0x07,0x13] + + for i in range(numClkOut): + + ############################### + # CLKOUT0 + ############################### + if (i==0): + + if (type is 'MMCME2') or (type is 'MMCME3') or (type is 'MMCME4'): + + self.add(pr.RemoteVariable( + name = 'FRAC[0]', + description = """ + Fractional divide counter setting for CLKOUT0. Equivalent to + additional divide of 1/8. + """, + offset = (ClkReg2[i] << 2), + bitSize = 3, + bitOffset = 12, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_EN[0]', + description = """ + Enable fractional divider circuitry for CLKOUT0. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 11, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_WF_R[0]', + description = """ + Adjusts CLKOUT0 rising edge for improved duty cycle accuracy + when using fractional counter. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 10, + mode = "RW", + )) + + + ############################### + # CLKOUT1 + ############################### + if (i==1): + if (type is 'PLLE3') or (type is 'PLLE4'): + self.add(pr.RemoteVariable( + name = f'CLKOUTPHY_MODE[{i}]', + description = """ + For the PLLE3 and PLLE4, determines CLKPHYOUT + frequency based on the VCO frequency. + """, + offset = (ClkReg2[i] << 2), + bitSize = 2, + bitOffset = 13, + mode = "RW", + )) + + ############################################## + # CLKOUT5 register with CLKOUT0 Configurations + ############################################## + if (i==5): + if (type is 'MMCME2') or (type is 'MMCME3') or (type is 'MMCME4'): + self.add(pr.RemoteVariable( + name = 'PHASE_MUX_F_CLKOUT[0]', + description = """ + CLKOUT0 data required when using fractional + counter. Chooses an initial phase offset for the + falling edge of the clock output. The resolution is + equal to 1/8 VCO period. Not available in UltraScale + PLLE3 and UltraScale+ PLLE4. + """, + offset = (ClkReg2[i] << 2), + bitSize = 3, + bitOffset = 13 if UltraScale else 11, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_WF_F_CLKOUT[0]', + description = """ + Adjusts CLKOUT0 falling edge for improved duty + cycle accuracy when using fractional counter. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 12 if UltraScale else 10, + mode = "RW", + )) + + ############################################### + # CLKOUT6 register with CLKFBOUT Configurations + ############################################### + if (i==6): + if (type is 'MMCME2') or (type is 'MMCME3') or (type is 'MMCME4'): + self.add(pr.RemoteVariable( + name = 'PHASE_MUX_F_CLKOUT_FB', + description = """ + CLKFBOUT data required when using fractional + counter. Chooses an initial phase offset for the + falling edge of the clock output. The resolution is + equal to 1/8 VCO period. Not available in UltraScale + PLLE3 and UltraScale+ PLLE4. + """, + offset = (ClkReg2[i] << 2), + bitSize = 3, + bitOffset = 13 if UltraScale else 11, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_WF_F_CLKOUT_FB', + description = """ + Adjusts CLKFBOUT falling edge for improved duty + cycle accuracy when using fractional counter. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 12 if UltraScale else 10, + mode = "RW", + )) + + ############################################################################## + + self.add(pr.RemoteVariable( + name = f'MX[{i}]', + description = """ + Must be set to 2'b00. + """, + offset = (ClkReg2[i] << 2), + bitSize = 2, + bitOffset = 8, + mode = "WO", + )) + + self.add(pr.RemoteVariable( + name = f'EDGE[{i}]', + description = """ + Chooses the edge that the High Time counter transitions on. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 7, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = f'NO_COUNT[{i}]', + description = """ + Bypasses the High and Low Time counters. + """, + offset = (ClkReg2[i] << 2), + bitSize = 1, + bitOffset = 6, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = f'DELAY_TIME[{i}]', + description = """ + Phase offset with a resolution equal to the VCO period. + """, + offset = (ClkReg2[i] << 2), + bitSize = 6, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + + if (type is 'MMCME2') or (type is 'MMCME3') or (type is 'MMCME4'): + + self.add(pr.RemoteVariable( + name = 'FRAC_FB', + description = """ + Fractional divide counter setting for CLKFBOUT. Equivalent to + additional divide of 1/8. + """, + offset = (0x15 << 2), + bitSize = 3, + bitOffset = 12, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_EN_FB', + description = """ + Enable fractional divider circuitry for CLKFBOUT. + """, + offset = (0x15 << 2), + bitSize = 1, + bitOffset = 11, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FRAC_WF_R_FB', + description = """ + Adjusts CLKFBOUT rising edge for improved duty cycle accuracy + when using fractional counter. + """, + offset = (0x15 << 2), + bitSize = 1, + bitOffset = 10, + mode = "RW", + )) + + ############################################################################## + # CLKFBOUT Register 2 (Address=0x15) + ############################################################################## + + self.add(pr.RemoteVariable( + name = 'MX_FB', + description = """ + Must be set to 2'b00. + """, + offset = (0x15 << 2), + bitSize = 2, + bitOffset = 8, + mode = "WO", + )) + + self.add(pr.RemoteVariable( + name = 'EDGE_FB', + description = """ + Chooses the edge that the High Time counter transitions on. + """, + offset = (0x15 << 2), + bitSize = 1, + bitOffset = 7, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'NO_COUNT_FB', + description = """ + Bypasses the High and Low Time counters. + """, + offset = (0x15 << 2), + bitSize = 1, + bitOffset = 6, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'DELAY_TIME_FB', + description = """ + Phase offset with a resolution equal to the VCO period. + """, + offset = (0x15 << 2), + bitSize = 6, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # DIVCLK Bitmap + ############################################################################## + # DIVCLK Register (Address=0x16) + + self.add(pr.RemoteVariable( + name = 'EDGE_DIV', + description = """ + Chooses the edge that the High Time counter transitions on. + """, + offset = (0x16 << 2), + bitSize = 1, + bitOffset = 13, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'NO_COUNT_DIV', + description = """ + Bypasses the High and Low Time counters. + """, + offset = (0x16 << 2), + bitSize = 1, + bitOffset = 12, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'HIGH_TIME_DIV', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains High. + """, + offset = (0x16 << 2), + bitSize = 6, + bitOffset = 6, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'LOW_TIME_DIV', + description = """ + Sets the amount of time in VCO cycles that the clock output + remains Low. + """, + offset = (0x16 << 2), + bitSize = 6, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # Lock Group Bitmap + ############################################################################## + # Lock Register 1 (Address=0x18) + # Lock Register 2 (Address=0x19) + # Lock Register 3 (Address=0x1A) + + self.add(pr.RemoteVariable( + name = 'LockReg[0]', + description = """ + Three additional LOCK configuration registers must also be updated based on how the MMCM + is programmed. These values are automatically setup by the reference design. + """, + offset = (0x18 << 2), + bitSize = 16, + bitOffset = 0, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'LockReg[1]', + description = """ + Three additional LOCK configuration registers must also be updated based on how the MMCM + is programmed. These values are automatically setup by the reference design. + """, + offset = (0x19 << 2), + bitSize = 16, + bitOffset = 0, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'LockReg[2]', + description = """ + Three additional LOCK configuration registers must also be updated based on how the MMCM + is programmed. These values are automatically setup by the reference design. + """, + offset = (0x1A << 2), + bitSize = 16, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # Filter Group Bitmap + ############################################################################## + # Filter Register 1 (Address=0x4E) + # Filter Register 2 (Address=0x4F) + self.add(pr.RemoteVariable( + name = 'FiltReg[0]', + description = """ + This bit is pulled from the lookup table provided in the reference design. + """, + offset = (0x4E << 2), + bitSize = 16, + bitOffset = 0, + mode = "RW", + )) + + self.add(pr.RemoteVariable( + name = 'FiltReg[1]', + description = """ + This bit is pulled from the lookup table provided in the reference design. + """, + offset = (0x4F << 2), + bitSize = 16, + bitOffset = 0, + mode = "RW", + )) + + ############################################################################## + # PowerReg Bitmap + ############################################################################## + # Power Register (Address=0x27): UltraScale and UltraScale+ + # Power Register (Address=0x28): 7 series + + self.add(pr.RemoteVariable( + name = 'POWER', + description = """ + These bits must all be set High when performing DRP. + """, + offset = (0x27 << 2) if (UltraScale) else (0x28 << 2), + bitSize = 16, + bitOffset = 0, + mode = "WO", + value = 0xFFFF + )) diff --git a/python/surf/xilinx/__init__.py b/python/surf/xilinx/__init__.py index 32780e3cdd..064b33b99f 100644 --- a/python/surf/xilinx/__init__.py +++ b/python/surf/xilinx/__init__.py @@ -8,9 +8,10 @@ ## may be copied, modified, propagated, or distributed except according to ## the terms contained in the LICENSE.txt file. ############################################################################## -from surf.xilinx._AxiPciePhy import * +from surf.xilinx._AxiPciePhy import * from surf.xilinx._AxiSysMonUltraScale import * -from surf.xilinx._Gthe3Channel import * -from surf.xilinx._Gtpe2Channel import * -from surf.xilinx._Gtpe2Common import * -from surf.xilinx._Xadc import * +from surf.xilinx._ClockManager import * +from surf.xilinx._Gthe3Channel import * +from surf.xilinx._Gtpe2Channel import * +from surf.xilinx._Gtpe2Common import * +from surf.xilinx._Xadc import * From 0e0e7d281f1fa871422e7b1e40188ed64c1b5006 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Mar 2019 12:55:22 -0700 Subject: [PATCH 54/92] Expand maxClkGap bits Typo fixes --- protocols/batcher/rtl/AxiStreamBatcher.vhd | 8 ++++---- protocols/batcher/rtl/AxiStreamBatcherAxil.vhd | 4 ++-- python/surf/protocols/batcher/_AxiStreamBatcherAxil.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcher.vhd b/protocols/batcher/rtl/AxiStreamBatcher.vhd index 008b15ea1d..54dd433bb7 100644 --- a/protocols/batcher/rtl/AxiStreamBatcher.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcher.vhd @@ -39,7 +39,7 @@ entity AxiStreamBatcher is -- External Control Interface superFrameByteThreshold : in slv(31 downto 0) := toSlv(SUPER_FRAME_BYTE_THRESHOLD_G, 32); maxSubFrames : in slv(15 downto 0) := toSlv(MAX_NUMBER_SUB_FRAMES_G, 16); - maxClkGap : in slv(11 downto 0) := toSlv(MAX_CLK_GAP_G, 12); + maxClkGap : in slv(31 downto 0) := toSlv(MAX_CLK_GAP_G, 32); idle : out sl; -- AXIS Interfaces sAxisMaster : in AxiStreamMasterType; @@ -68,8 +68,8 @@ architecture rtl of AxiStreamBatcher is subByteCnt : slv(31 downto 0); maxSubFrames : slv(15 downto 0); subFrameCnt : slv(15 downto 0); - maxClkGap : slv(11 downto 0); - clkGapCnt : slv(11 downto 0); + maxClkGap : slv(31 downto 0); + clkGapCnt : slv(31 downto 0); superFrameByteThresholdDet : sl; maxSubFramesDet : sl; seqCnt : slv(7 downto 0); @@ -88,7 +88,7 @@ architecture rtl of AxiStreamBatcher is subByteCnt => (others => '0'), maxSubFrames => toSlv(MAX_NUMBER_SUB_FRAMES_G, 16), subFrameCnt => (others => '0'), - maxClkGap => toSlv(MAX_CLK_GAP_G, 12), + maxClkGap => toSlv(MAX_CLK_GAP_G, 32), clkGapCnt => (others => '0'), superFrameByteThresholdDet => '0', maxSubFramesDet => '0', diff --git a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd index 166e983525..5f10cefc2a 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd @@ -58,7 +58,7 @@ architecture rtl of AxiStreamBatcherAxil is type RegType is record superFrameByteThreshold : slv(31 downto 0); maxSubFrames : slv(15 downto 0); - maxClkGap : slv(11 downto 0); + maxClkGap : slv(31 downto 0); axilReadSlave : AxiLiteReadSlaveType; axilWriteSlave : AxiLiteWriteSlaveType; end record RegType; @@ -66,7 +66,7 @@ architecture rtl of AxiStreamBatcherAxil is constant REG_INIT_C : RegType := ( superFrameByteThreshold => toSlv(SUPER_FRAME_BYTE_THRESHOLD_G, 32), maxSubFrames => toSlv(MAX_NUMBER_SUB_FRAMES_G, 16), - maxClkGap => toSlv(MAX_CLK_GAP_G, 12), + maxClkGap => toSlv(MAX_CLK_GAP_G, 32), axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C); diff --git a/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py b/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py index da8181bb58..c481eb69cc 100644 --- a/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py +++ b/python/surf/protocols/batcher/_AxiStreamBatcherAxil.py @@ -26,7 +26,7 @@ def __init__(self, **kwargs): name = 'MaxClkGap', offset = 0x08, bitOffset = 0, - bitSize = 12, + bitSize = 32, mode = 'RW', base = pr.UInt, disp = '{:d}')) From 5c74e3031da23a4dd9d409ea9a5dfc225c6a401c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Mar 2019 13:57:33 -0700 Subject: [PATCH 55/92] bug fix --- protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd index 7a6ae36e28..1c8c84f2c1 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherEventBuilder.vhd @@ -216,16 +216,12 @@ begin if (r.hardRst = '1') or (r.softRst = '1') then -- Reset the register v := REG_INIT_C; - - -- -- Check for soft reset (unclear if we want to support a hard reset that also resets the registers. it might confuse 'novice' users who randomly hitting different resets) - -- if (r.softRst = '1') then - + -- Preserve the resister configurations + v.bypass := r.bypass; v.timeout := r.timeout; v.blowoff := r.blowoff; - - -- end if; - + end if; -- Determine the transaction type From a85e09077305ebf6f6300fff2d14b8b47fb96890 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Tue, 26 Mar 2019 15:24:45 -0700 Subject: [PATCH 56/92] Update sensitivity list --- protocols/batcher/rtl/AxiStreamBatcherAxil.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd index 5f10cefc2a..2e09b0ecf7 100644 --- a/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd +++ b/protocols/batcher/rtl/AxiStreamBatcherAxil.vhd @@ -119,7 +119,7 @@ begin mAxiWriteMaster => syncAxilWriteMaster, -- [out] mAxiWriteSlave => r.axilWriteSlave); -- [in] - comb : process (r, syncAxilReadMaster, syncAxilWriteMaster) is + comb : process (axisRst, r, syncAxilReadMaster, syncAxilWriteMaster) is variable v : RegType; variable axilEp : AxiLiteEndpointType; begin From b081d06c5de5075700aaad4eb67bff6c300952f4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Mar 2019 16:00:40 -0700 Subject: [PATCH 57/92] adding DRP interface to MMCMs --- protocols/clink/hdl/ClinkData.vhd | 70 ++-- protocols/clink/hdl/ClinkDataClk.vhd | 118 ++++-- protocols/clink/hdl/ClinkDataShift.vhd | 206 +++++---- protocols/clink/hdl/ClinkFraming.vhd | 3 +- protocols/clink/hdl/ClinkPkg.vhd | 22 +- protocols/clink/hdl/ClinkReg.vhd | 210 ++++++++++ protocols/clink/hdl/ClinkTop.vhd | 420 +++++++++---------- python/surf/protocols/clink/_ClinkChannel.py | 35 +- python/surf/protocols/clink/_ClinkTop.py | 52 ++- 9 files changed, 755 insertions(+), 381 deletions(-) create mode 100644 protocols/clink/hdl/ClinkReg.vhd diff --git a/protocols/clink/hdl/ClinkData.vhd b/protocols/clink/hdl/ClinkData.vhd index 6ad571567e..8c8a9ea343 100644 --- a/protocols/clink/hdl/ClinkData.vhd +++ b/protocols/clink/hdl/ClinkData.vhd @@ -19,32 +19,39 @@ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; + use work.StdRtlPkg.all; +use work.AxiLitePkg.all; use work.ClinkPkg.all; + library unisim; use unisim.vcomponents.all; entity ClinkData is generic ( - TPD_G : time := 1 ns - ); + TPD_G : time := 1 ns); port ( -- Cable Input - cblHalfP : inout slv(4 downto 0); -- 8, 10, 11, 12, 9 - cblHalfM : inout slv(4 downto 0); -- 21, 23, 24, 25, 22 + cblHalfP : inout slv(4 downto 0); -- 8, 10, 11, 12, 9 + cblHalfM : inout slv(4 downto 0); -- 21, 23, 24, 25, 22 -- Delay clock, 200Mhz - dlyClk : in sl; - dlyRst : in sl; + dlyClk : in sl; + dlyRst : in sl; -- System clock and reset, must be 100Mhz or greater - sysClk : in sl; - sysRst : in sl; + sysClk : in sl; + sysRst : in sl; -- Status and config - linkConfig : in ClLinkConfigType; - linkStatus : out ClLinkStatusType; + linkConfig : in ClLinkConfigType; + linkStatus : out ClLinkStatusType; -- Data output - parData : out slv(27 downto 0); - parValid : out sl; - parReady : in sl); + parData : out slv(27 downto 0); + parValid : out sl; + parReady : in sl; + -- AXI-Lite Interface + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); end ClinkData; architecture rtl of ClinkData is @@ -96,18 +103,31 @@ begin U_DataShift : entity work.ClinkDataShift generic map (TPD_G => TPD_G) port map ( - cblHalfP => cblHalfP, - cblHalfM => cblHalfM, - linkRst => linkConfig.rstPll, - dlyClk => dlyClk, - dlyRst => dlyRst, - clinkClk => clinkClk, - clinkRst => clinkRst, - parData => intData, - parClock => parClock, - delay => r.delay, - delayLd => r.delayLd, - bitSlip => r.bitSlip); + cblHalfP => cblHalfP, + cblHalfM => cblHalfM, + linkRst => linkConfig.rstPll, + dlyClk => dlyClk, + dlyRst => dlyRst, + clinkClk => clinkClk, + clinkRst => clinkRst, + -- Parallel clock and data output (clinkClk) + parData => intData, + parClock => parClock, + -- Control inputs + delay => r.delay, + delayLd => r.delayLd, + bitSlip => r.bitSlip, + -- Frequency Measurements + clkInFreq => linkStatus.clkInFreq, + clinkClkFreq => linkStatus.clinkClkFreq, + clinkClk7xFreq => linkStatus.clinkClk7xFreq, + -- AXI-Lite Interface + sysClk => sysClk, + sysRst => sysRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave); ------------------------------- -- State Machine diff --git a/protocols/clink/hdl/ClinkDataClk.vhd b/protocols/clink/hdl/ClinkDataClk.vhd index b9c2225ced..8e73d383d5 100644 --- a/protocols/clink/hdl/ClinkDataClk.vhd +++ b/protocols/clink/hdl/ClinkDataClk.vhd @@ -23,17 +23,25 @@ library unisim; use unisim.vcomponents.all; use work.StdRtlPkg.all; +use work.AxiLitePkg.all; entity ClinkDataClk is - generic ( + generic ( TPD_G : time := 1 ns; REG_BUFF_EN_G : boolean := false); port ( - clkIn : in sl; - rstIn : in sl; - clinkClk7x : out sl; - clinkClk : out sl; - clinkRst : out sl); + clkIn : in sl; + rstIn : in sl; + clinkClk7x : out sl; + clinkClk : out sl; + clinkRst : out sl; + -- AXI-Lite Interface + sysClk : in sl; + sysRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); end entity ClinkDataClk; architecture rtl of ClinkDataClk is @@ -46,26 +54,59 @@ architecture rtl of ClinkDataClk is signal lockedLoc : sl; signal genReset : sl; + signal drpRdy : sl; + signal drpEn : sl; + signal drpWe : sl; + signal drpAddr : slv(6 downto 0); + signal drpDi : slv(15 downto 0); + signal drpDo : slv(15 downto 0); + begin + U_AxiLiteToDrp : entity work.AxiLiteToDrp + generic map ( + TPD_G => TPD_G, + COMMON_CLK_G => true, + EN_ARBITRATION_G => false, + TIMEOUT_G => 4096, + ADDR_WIDTH_G => 7, + DATA_WIDTH_G => 16) + port map ( + -- AXI-Lite Port + axilClk => sysClk, + axilRst => sysRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave, + -- DRP Interface + drpClk => sysClk, + drpRst => sysRst, + drpRdy => drpRdy, + drpEn => drpEn, + drpWe => drpWe, + drpAddr => drpAddr, + drpDi => drpDi, + drpDo => drpDo); + U_Mmcm : MMCME2_ADV generic map ( - BANDWIDTH => "OPTIMIZED", - CLKOUT4_CASCADE => false, - STARTUP_WAIT => false, - CLKIN1_PERIOD => 11.764, -- 85Mhz - DIVCLK_DIVIDE => 1, - CLKFBOUT_MULT_F => 14.0, -- 1190Mhz - CLKOUT0_DIVIDE_F => 14.0, -- 85Mhz - CLKOUT1_DIVIDE => 2) -- 595Mhz + BANDWIDTH => "OPTIMIZED", + CLKOUT4_CASCADE => false, + STARTUP_WAIT => false, + CLKIN1_PERIOD => 11.764, -- 85Mhz + DIVCLK_DIVIDE => 1, + CLKFBOUT_MULT_F => 14.0, -- 1190Mhz + CLKOUT0_DIVIDE_F => 14.0, -- 85Mhz + CLKOUT1_DIVIDE => 2) -- 595Mhz port map ( - DCLK => '0', - DRDY => open, - DEN => '0', - DWE => '0', - DADDR => (others=>'0'), - DI => (others=>'0'), - DO => open, + DCLK => sysClk, + DRDY => drpRdy, + DEN => drpEn, + DWE => drpWe, + DADDR => drpAddr, + DI => drpDi, + DO => drpDo, PSCLK => '0', PSEN => '0', PSINCDEC => '0', @@ -80,7 +121,7 @@ begin CLKOUT0 => clkOutMmcm(0), CLKOUT1 => clkOutMmcm(1)); - U_RegGen: if REG_BUFF_EN_G generate + U_RegGen : if REG_BUFF_EN_G generate U_BufIn : BUFR port map ( @@ -105,32 +146,32 @@ begin U_BufIo : BUFIO port map ( - I => clkOutMmcm(1), - O => clkOutLoc(1)); + I => clkOutMmcm(1), + O => clkOutLoc(1)); end generate; - U_GlbGen: if not REG_BUFF_EN_G generate + U_GlbGen : if not REG_BUFF_EN_G generate U_BufIn : BUFG port map ( - I => clkIn, - O => clkInLoc); + I => clkIn, + O => clkInLoc); U_BufFb : BUFG port map ( - I => clkFbOut, - O => clkFbIn); + I => clkFbOut, + O => clkFbIn); U_BufOut : BUFG port map ( - I => clkOutMmcm(0), - O => clkOutLoc(0)); + I => clkOutMmcm(0), + O => clkOutLoc(0)); U_BufIo : BUFG port map ( - I => clkOutMmcm(1), - O => clkOutLoc(1)); + I => clkOutMmcm(1), + O => clkOutLoc(1)); end generate; @@ -138,10 +179,10 @@ begin U_RstSync : entity work.RstSync generic map ( - TPD_G => TPD_G, - IN_POLARITY_G => '0', - OUT_POLARITY_G => '1', - BYPASS_SYNC_G => false) + TPD_G => TPD_G, + IN_POLARITY_G => '0', + OUT_POLARITY_G => '1', + BYPASS_SYNC_G => false) port map ( clk => clkOutLoc(0), asyncRst => genReset, @@ -150,5 +191,4 @@ begin clinkClk <= clkOutLoc(0); clinkClk7x <= clkOutLoc(1); -end architecture rtl; - +end rtl; diff --git a/protocols/clink/hdl/ClinkDataShift.vhd b/protocols/clink/hdl/ClinkDataShift.vhd index 269ccc0b7f..b2f3b31650 100644 --- a/protocols/clink/hdl/ClinkDataShift.vhd +++ b/protocols/clink/hdl/ClinkDataShift.vhd @@ -18,66 +18,128 @@ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; + use work.StdRtlPkg.all; use work.AxiLitePkg.all; use work.ClinkPkg.all; + library unisim; use unisim.vcomponents.all; entity ClinkDataShift is - generic ( - TPD_G : time := 1 ns - ); + generic ( + TPD_G : time := 1 ns + ); port ( -- Input clock and data - cblHalfP : inout slv(4 downto 0); - cblHalfM : inout slv(4 downto 0); + cblHalfP : inout slv(4 downto 0); + cblHalfM : inout slv(4 downto 0); -- Async link reset - linkRst : in sl; + linkRst : in sl; -- Delay clock, 200Mhz - dlyClk : in sl; - dlyRst : in sl; - -- Parrallel Clock and reset Output, 85Mhz - clinkClk : out sl; - clinkRst : out sl; - -- Parrallel clock and data output (clinkClk) - parData : out slv(27 downto 0); - parClock : out slv(6 downto 0); + dlyClk : in sl; + dlyRst : in sl; + -- Parallel Clock and reset Output, 85Mhz + clinkClk : out sl; + clinkRst : out sl; + -- Parallel clock and data output (clinkClk) + parData : out slv(27 downto 0); + parClock : out slv(6 downto 0); -- Control inputs - delay : in slv(4 downto 0); - delayLd : in sl; - bitSlip : in sl); + delay : in slv(4 downto 0); + delayLd : in sl; + bitSlip : in sl; + -- Frequency Measurements + clkInFreq : out slv(31 downto 0); + clinkClkFreq : out slv(31 downto 0); + clinkClk7xFreq : out slv(31 downto 0); + -- AXI-Lite Interface + sysClk : in sl; + sysRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); end ClinkDataShift; architecture structure of ClinkDataShift is - signal intClk : sl; - signal intRst : sl; - signal intClk7x : sl; - signal intClk7xInv : sl; - signal intDelay : slv(4 downto 0); - signal intLd : sl; - signal cblInDly : slv(4 downto 0); - signal cblIn : slv(4 downto 0); - signal rawIn : slv(4 downto 0); - signal dataShift : Slv7Array(4 downto 0); - signal clkReset : sl; + signal intClk : sl; + signal intRst : sl; + signal intClk7x : sl; + signal intClk7xInv : sl; + signal intDelay : slv(4 downto 0); + signal intLd : sl; + signal cblInDly : slv(4 downto 0); + signal cblIn : slv(4 downto 0); + signal rawIn : slv(4 downto 0); + signal dataShift : Slv7Array(4 downto 0); + signal clkReset : sl; - attribute IODELAY_GROUP : string; + attribute IODELAY_GROUP : string; begin + U_clkInFreq : entity work.SyncClockFreq + generic map ( + TPD_G => TPD_G, + REF_CLK_FREQ_G => 200.0E+6, + REFRESH_RATE_G => 1.0, + CNT_WIDTH_G => 32) + port map ( + -- Frequency Measurement (locClk domain) + freqOut => clkInFreq, + -- Clocks + clkIn => rawIn(0), + locClk => sysClk, + refClk => dlyClk); + + U_clinkClkFreq : entity work.SyncClockFreq + generic map ( + TPD_G => TPD_G, + REF_CLK_FREQ_G => 200.0E+6, + REFRESH_RATE_G => 1.0, + CNT_WIDTH_G => 32) + port map ( + -- Frequency Measurement (locClk domain) + freqOut => clinkClkFreq, + -- Clocks + clkIn => intClk, + locClk => sysClk, + refClk => dlyClk); + + U_clinkClk7xFreq : entity work.SyncClockFreq + generic map ( + TPD_G => TPD_G, + REF_CLK_FREQ_G => 200.0E+6, + REFRESH_RATE_G => 1.0, + CNT_WIDTH_G => 32) + port map ( + -- Frequency Measurement (locClk domain) + freqOut => clinkClk7xFreq, + -- Clocks + clkIn => intClk7x, + locClk => sysClk, + refClk => dlyClk); + -------------------------------------- -- Clock Generation -------------------------------------- U_ClkGen : entity work.ClinkDataClk - generic map ( TPD_G => TPD_G ) + generic map (TPD_G => TPD_G) port map ( - clkIn => rawIn(0), - rstIn => clkReset, - clinkClk => intClk, - clinkClk7x => intClk7x, - clinkRst => intRst); + clkIn => rawIn(0), + rstIn => clkReset, + clinkClk => intClk, + clinkClk7x => intClk7x, + clinkRst => intRst, + -- AXI-Lite Interface + sysClk => sysClk, + sysRst => sysRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave); -- Clock reset clkReset <= linkRst or dlyRst; @@ -91,7 +153,7 @@ begin U_SyncDelay : entity work.SynchronizerFifo generic map ( TPD_G => TPD_G, - DATA_WIDTH_G => 5 ) + DATA_WIDTH_G => 5) port map ( rst => intRst, wr_clk => intClk, @@ -104,12 +166,12 @@ begin -------------------------------------- -- Input Chain -------------------------------------- - U_InputGen: for i in 0 to 4 generate + U_InputGen : for i in 0 to 4 generate attribute IODELAY_GROUP of U_Delay : label is "CLINK_CORE"; begin -- Input buffer - U_InBuff: IOBUFDS + U_InBuff : IOBUFDS port map( I => '0', O => cblIn(i), @@ -121,43 +183,43 @@ begin -- Input rate = 85Mhz * 7 = 595Mhz = 1.68nS = 21.55 taps U_Delay : IDELAYE2 generic map ( - CINVCTRL_SEL => "FALSE", -- Enable dynamic clock inversion (FALSE, TRUE) - DELAY_SRC => "IDATAIN", -- Delay input (IDATAIN, DATAIN) - HIGH_PERFORMANCE_MODE => "TRUE", -- Reduced jitter ("TRUE"), Reduced power ("FALSE") - IDELAY_TYPE => "VAR_LOAD", -- FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE - IDELAY_VALUE => 0, -- Input delay tap setting (0-31) - PIPE_SEL => "FALSE", -- Select pipelined mode, FALSE, TRUE - REFCLK_FREQUENCY => 200.0, -- IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). - SIGNAL_PATTERN => "DATA" -- DATA, CLOCK input signal - ) + CINVCTRL_SEL => "FALSE", -- Enable dynamic clock inversion (FALSE, TRUE) + DELAY_SRC => "IDATAIN", -- Delay input (IDATAIN, DATAIN) + HIGH_PERFORMANCE_MODE => "TRUE", -- Reduced jitter ("TRUE"), Reduced power ("FALSE") + IDELAY_TYPE => "VAR_LOAD", -- FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE + IDELAY_VALUE => 0, -- Input delay tap setting (0-31) + PIPE_SEL => "FALSE", -- Select pipelined mode, FALSE, TRUE + REFCLK_FREQUENCY => 200.0, -- IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). + SIGNAL_PATTERN => "DATA" -- DATA, CLOCK input signal + ) port map ( CNTVALUEOUT => open, -- 5-bit output: Counter value output - DATAOUT => cblInDly(i), -- 1-bit output: Delayed data output + DATAOUT => cblInDly(i), -- 1-bit output: Delayed data output C => dlyClk, -- 1-bit input: Clock input - CE => '0', -- 1-bit input: Active high enable increment/decrement input - CINVCTRL => '0', -- 1-bit input: Dynamic clock inversion input + CE => '0', -- 1-bit input: Active high enable increment/decrement input + CINVCTRL => '0', -- 1-bit input: Dynamic clock inversion input CNTVALUEIN => intDelay, -- 5-bit input: Counter value input - DATAIN => '0', -- 1-bit input: Internal delay data input + DATAIN => '0', -- 1-bit input: Internal delay data input IDATAIN => cblIn(i), -- 1-bit input: Data input from the I/O - INC => '0', -- 1-bit input: Increment / Decrement tap delay input + INC => '0', -- 1-bit input: Increment / Decrement tap delay input LD => intLd, -- 1-bit input: Load IDELAY_VALUE input - LDPIPEEN => '0', -- 1-bit input: Enable PIPELINE register to load data input - REGRST => '0' -- 1-bit input: Active-high reset tap-delay input - ); + LDPIPEEN => '0', -- 1-bit input: Enable PIPELINE register to load data input + REGRST => '0' -- 1-bit input: Active-high reset tap-delay input + ); -- Deserializer U_Serdes : ISERDESE2 generic map ( - DATA_RATE => "SDR", -- DDR, SDR - DATA_WIDTH => 7, -- Parallel data width (2-8,10,14) + DATA_RATE => "SDR", -- DDR, SDR + DATA_WIDTH => 7, -- Parallel data width (2-8,10,14) DYN_CLKDIV_INV_EN => "FALSE", DYN_CLK_INV_EN => "FALSE", - INTERFACE_TYPE => "NETWORKING", -- MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE - IOBDELAY => "IFD", -- NONE, BOTH, IBUF, IFD - NUM_CE => 1, -- Number of clock enables (1,2) - OFB_USED => "FALSE", -- Select OFB path (FALSE, TRUE) - SERDES_MODE => "MASTER" -- MASTER, SLAVE - ) + INTERFACE_TYPE => "NETWORKING", -- MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE + IOBDELAY => "IFD", -- NONE, BOTH, IBUF, IFD + NUM_CE => 1, -- Number of clock enables (1,2) + OFB_USED => "FALSE", -- Select OFB path (FALSE, TRUE) + SERDES_MODE => "MASTER" -- MASTER, SLAVE + ) port map ( Q1 => dataShift(i)(0), Q2 => dataShift(i)(1), @@ -184,7 +246,7 @@ begin RST => intRst, SHIFTIN1 => '0', SHIFTIN2 => '0' - ); + ); end generate; @@ -200,13 +262,13 @@ begin -- Iserdes Bits -- 6 5 4 3 2 1 0 ------------------------------------------------------- - parData(7) <= dataShift(1)(6); - parData(6) <= dataShift(1)(5); - parData(4) <= dataShift(1)(4); - parData(3) <= dataShift(1)(3); - parData(2) <= dataShift(1)(2); - parData(1) <= dataShift(1)(1); - parData(0) <= dataShift(1)(0); + parData(7) <= dataShift(1)(6); + parData(6) <= dataShift(1)(5); + parData(4) <= dataShift(1)(4); + parData(3) <= dataShift(1)(3); + parData(2) <= dataShift(1)(2); + parData(1) <= dataShift(1)(1); + parData(0) <= dataShift(1)(0); parData(18) <= dataShift(2)(6); parData(15) <= dataShift(2)(5); @@ -224,7 +286,7 @@ begin parData(20) <= dataShift(3)(1); parData(19) <= dataShift(3)(0); - parData(23) <= dataShift(4)(6); + parData(23) <= dataShift(4)(6); parData(17) <= dataShift(4)(5); parData(16) <= dataShift(4)(4); parData(11) <= dataShift(4)(3); diff --git a/protocols/clink/hdl/ClinkFraming.vhd b/protocols/clink/hdl/ClinkFraming.vhd index a1bdd2e998..741cbd2b29 100644 --- a/protocols/clink/hdl/ClinkFraming.vhd +++ b/protocols/clink/hdl/ClinkFraming.vhd @@ -26,6 +26,7 @@ use work.ClinkPkg.all; entity ClinkFraming is generic ( TPD_G : time := 1 ns; + COMMON_DATA_CLK_G : boolean := false; -- true if dataClk=sysClk DATA_AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- System clock and reset @@ -439,7 +440,7 @@ begin generic map ( TPD_G => TPD_G, SLAVE_READY_EN_G => false, - GEN_SYNC_FIFO_G => false, + GEN_SYNC_FIFO_G => COMMON_DATA_CLK_G, FIFO_ADDR_WIDTH_G => 9, FIFO_PAUSE_THRESH_G => 500, SLAVE_AXI_CONFIG_G => MST_CONFIG_C, diff --git a/protocols/clink/hdl/ClinkPkg.vhd b/protocols/clink/hdl/ClinkPkg.vhd index 043a781c7e..041969b619 100644 --- a/protocols/clink/hdl/ClinkPkg.vhd +++ b/protocols/clink/hdl/ClinkPkg.vhd @@ -71,15 +71,21 @@ package ClinkPkg is -- Link Status Record ------------------------------------ type ClLinkStatusType is record - locked : sl; - delay : slv(4 downto 0); - shiftCnt : slv(2 downto 0); + clkInFreq : slv(31 downto 0); + clinkClkFreq : slv(31 downto 0); + clinkClk7xFreq : slv(31 downto 0); + locked : sl; + delay : slv(4 downto 0); + shiftCnt : slv(2 downto 0); end record ClLinkStatusType; constant CL_LINK_STATUS_INIT_C : ClLinkStatusType := ( - locked => '0', - delay => (others => '0'), - shiftCnt => (others => '0')); + clkInFreq => (others => '0'), + clinkClkFreq => (others => '0'), + clinkClk7xFreq => (others => '0'), + locked => '0', + delay => (others => '0'), + shiftCnt => (others => '0')); type ClLinkStatusArray is array (natural range<>) of ClLinkStatusType; @@ -103,8 +109,8 @@ package ClinkPkg is constant CL_CHAN_CONFIG_INIT_C : ClChanConfigType := ( swCamCtrl => (others => '0'), swCamCtrlEn => (others => '0'), - serBaud => toSlv(57600, 24), -- Default of 57600 baud - serThrottle => (others => '1'), -- Default of 65ms per byte throttle rate + serBaud => toSlv(9600, 24), -- Default of 9600 baud + serThrottle => toSlv(10000, 16), -- Default of 10ms per byte throttle rate linkMode => (others => '0'), dataMode => (others => '0'), tapCount => (others => '0'), diff --git a/protocols/clink/hdl/ClinkReg.vhd b/protocols/clink/hdl/ClinkReg.vhd new file mode 100644 index 0000000000..4ee7f529f6 --- /dev/null +++ b/protocols/clink/hdl/ClinkReg.vhd @@ -0,0 +1,210 @@ +------------------------------------------------------------------------------- +-- File : ClinkReg.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: +-- CameraLink Registers +------------------------------------------------------------------------------- +-- 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; +use work.StdRtlPkg.all; +use work.ClinkPkg.all; +use work.AxiLitePkg.all; +use work.AxiStreamPkg.all; +library unisim; +use unisim.vcomponents.all; + +entity ClinkReg is + generic ( + TPD_G : time := 1 ns; + CHAN_COUNT_G : integer range 1 to 2 := 1); + port ( + chanStatus : in ClChanStatusArray(1 downto 0); + linkStatus : in ClLinkStatusArray(2 downto 0); + chanConfig : out ClChanConfigArray(1 downto 0); + linkConfig : out ClLinkConfigType; + -- Axi-Lite Interface + sysClk : in sl; + sysRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end ClinkReg; + +architecture rtl of ClinkReg is + + type RegType is record + locked : slv(2 downto 0); + lockCnt : Slv8Array(2 downto 0); + chanConfig : ClChanConfigArray(1 downto 0); + linkConfig : ClLinkConfigType; + axilReadSlave : AxiLiteReadSlaveType; + axilWriteSlave : AxiLiteWriteSlaveType; + end record RegType; + + constant REG_INIT_C : RegType := ( + locked => "000", + lockCnt => (others => x"00"), + chanConfig => (others => CL_CHAN_CONFIG_INIT_C), + linkConfig => CL_LINK_CONFIG_INIT_C, + axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, + axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + +begin + + --------------------------------- + -- Registers + --------------------------------- + comb : process (axilReadMaster, axilWriteMaster, chanStatus, linkStatus, r, + sysRst) is + + variable v : RegType; + variable axilEp : AxiLiteEndpointType; + variable i : natural; + begin + + -- Latch the current value + v := r; + + -- Loop through the locking channels + for i in 2 downto 0 loop + -- Keep delayed copy of the locks + v.locked(i) := linkStatus(i).locked; + -- Check for 0->1 lock transition and not max value + if (r.locked(i) = '0') and (linkStatus(i).locked = '1') and (r.lockCnt(i) /= x"FF") then + -- Increment the counter + v.lockCnt(i) := r.lockCnt(i) + 1; + end if; + end loop; + + -- Check for counter reset + if (r.linkConfig.cntRst = '1') then + v.lockCnt := (others => x"00"); + end if; + + ------------------------ + -- AXI-Lite Transactions + ------------------------ + + -- Determine the transaction type + axiSlaveWaitTxn(axilEp, axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave); + + -- Common Config + axiSlaveRegisterR(axilEp, x"000", 0, toSlv(CHAN_COUNT_G, 4)); + axiSlaveRegister (axilEp, x"004", 0, v.linkConfig.rstPll); + axiSlaveRegister (axilEp, x"004", 1, v.linkConfig.rstFsm); + axiSlaveRegister (axilEp, x"004", 2, v.linkConfig.cntRst); + + -- Common Status + axiSlaveRegisterR(axilEp, x"010", 0, linkStatus(0).locked); + axiSlaveRegisterR(axilEp, x"010", 1, linkStatus(1).locked); + axiSlaveRegisterR(axilEp, x"010", 2, linkStatus(2).locked); + axiSlaveRegisterR(axilEp, x"010", 8, r.lockCnt(0)); + axiSlaveRegisterR(axilEp, x"010", 16, r.lockCnt(1)); + axiSlaveRegisterR(axilEp, x"010", 24, r.lockCnt(2)); + axiSlaveRegisterR(axilEp, x"014", 0, linkStatus(0).shiftCnt); + axiSlaveRegisterR(axilEp, x"014", 8, linkStatus(1).shiftCnt); + axiSlaveRegisterR(axilEp, x"014", 16, linkStatus(2).shiftCnt); + axiSlaveRegisterR(axilEp, x"018", 0, linkStatus(0).delay); + axiSlaveRegisterR(axilEp, x"018", 8, linkStatus(1).delay); + axiSlaveRegisterR(axilEp, x"018", 16, linkStatus(2).delay); + + axiSlaveRegisterR(axilEp, x"01C", 0, linkStatus(0).clkInFreq); + axiSlaveRegisterR(axilEp, x"020", 0, linkStatus(1).clkInFreq); + axiSlaveRegisterR(axilEp, x"024", 0, linkStatus(2).clkInFreq); + + axiSlaveRegisterR(axilEp, x"028", 0, linkStatus(0).clinkClkFreq); + axiSlaveRegisterR(axilEp, x"02C", 0, linkStatus(1).clinkClkFreq); + axiSlaveRegisterR(axilEp, x"030", 0, linkStatus(2).clinkClkFreq); + + axiSlaveRegisterR(axilEp, x"034", 0, linkStatus(0).clinkClk7xFreq); + axiSlaveRegisterR(axilEp, x"038", 0, linkStatus(1).clinkClk7xFreq); + axiSlaveRegisterR(axilEp, x"03C", 0, linkStatus(2).clinkClk7xFreq); + + -- Channel A Config + axiSlaveRegister (axilEp, x"100", 0, v.chanConfig(0).linkMode); + axiSlaveRegister (axilEp, x"104", 0, v.chanConfig(0).dataMode); + axiSlaveRegister (axilEp, x"108", 0, v.chanConfig(0).frameMode); + axiSlaveRegister (axilEp, x"10C", 0, v.chanConfig(0).tapCount); + axiSlaveRegister (axilEp, x"110", 0, v.chanConfig(0).dataEn); + axiSlaveRegister (axilEp, x"110", 1, v.chanConfig(0).blowoff); + axiSlaveRegister (axilEp, x"110", 2, v.chanConfig(0).cntRst); + axiSlaveRegister (axilEp, x"110", 16, v.chanConfig(0).serThrottle); + axiSlaveRegister (axilEp, x"114", 0, v.chanConfig(0).serBaud); + axiSlaveRegister (axilEp, x"118", 0, v.chanConfig(0).swCamCtrlEn); + axiSlaveRegister (axilEp, x"11C", 0, v.chanConfig(0).swCamCtrl); + + -- Channel A Status + axiSlaveRegisterR(axilEp, x"120", 0, chanStatus(0).running); + axiSlaveRegisterR(axilEp, x"124", 0, chanStatus(0).frameCount); + axiSlaveRegisterR(axilEp, x"128", 0, chanStatus(0).dropCount); + + -- Channel B Config + axiSlaveRegister (axilEp, x"200", 0, v.chanConfig(1).linkMode); + axiSlaveRegister (axilEp, x"204", 0, v.chanConfig(1).dataMode); + axiSlaveRegister (axilEp, x"208", 0, v.chanConfig(1).frameMode); + axiSlaveRegister (axilEp, x"20C", 0, v.chanConfig(1).tapCount); + axiSlaveRegister (axilEp, x"210", 0, v.chanConfig(1).dataEn); + axiSlaveRegister (axilEp, x"210", 1, v.chanConfig(1).blowoff); + axiSlaveRegister (axilEp, x"210", 2, v.chanConfig(1).cntRst); + axiSlaveRegister (axilEp, x"210", 16, v.chanConfig(1).serThrottle); + axiSlaveRegister (axilEp, x"214", 0, v.chanConfig(1).serBaud); + axiSlaveRegister (axilEp, x"218", 0, v.chanConfig(1).swCamCtrlEn); + axiSlaveRegister (axilEp, x"21C", 0, v.chanConfig(1).swCamCtrl); + + -- Channel B Status + axiSlaveRegisterR(axilEp, x"220", 0, chanStatus(1).running); + axiSlaveRegisterR(axilEp, x"224", 0, chanStatus(1).frameCount); + axiSlaveRegisterR(axilEp, x"228", 0, chanStatus(1).dropCount); + + axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); + + -- Prevent zero baud rate + if (v.chanConfig(0).serBaud = 0) then + v.chanConfig(0).serBaud := toSlv(1, 24); + end if; + if (v.chanConfig(1).serBaud = 0) then + v.chanConfig(1).serBaud := toSlv(1, 24); + end if; + + ------------- + -- Reset + ------------- + if (sysRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + -- Outputs + axilReadSlave <= r.axilReadSlave; + axilWriteSlave <= r.axilWriteSlave; + chanConfig <= r.chanConfig; + linkConfig <= r.linkConfig; + + end process comb; + + seq : process (sysClk) is + begin + if (rising_edge(sysClk)) then + r <= rin after TPD_G; + end if; + end process seq; + +end rtl; diff --git a/protocols/clink/hdl/ClinkTop.vhd b/protocols/clink/hdl/ClinkTop.vhd index ef7ec383fc..4f7f7956d6 100644 --- a/protocols/clink/hdl/ClinkTop.vhd +++ b/protocols/clink/hdl/ClinkTop.vhd @@ -30,8 +30,11 @@ entity ClinkTop is TPD_G : time := 1 ns; CHAN_COUNT_G : integer range 1 to 2 := 1; UART_READY_EN_G : boolean := true; + COMMON_AXIL_CLK_G : boolean := false; -- true if axilClk=sysClk + COMMON_DATA_CLK_G : boolean := false; -- true if dataClk=sysClk DATA_AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C; - UART_AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); + UART_AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C; + AXIL_BASE_ADDR_G : slv(31 downto 0)); port ( -- Connector 0, Half 0, Control for Base,Medium,Full,Deca cbl0Half0P : inout slv(4 downto 0); -- 15, 17, 5, 6, 3 @@ -40,8 +43,8 @@ entity ClinkTop is cbl0Half1P : inout slv(4 downto 0); -- 8, 10, 11, 12, 9 cbl0Half1M : inout slv(4 downto 0); -- 21, 23, 24, 25, 22 -- Connector 0, Serial out - cbl0SerP : out sl; -- 20 - cbl0SerM : out sl; -- 7 + cbl0SerP : out sl; -- 20 + cbl0SerM : out sl; -- 7 -- Connector 1, Half 0, Control Base, Data Z for Med, Full, Deca cbl1Half0P : inout slv(4 downto 0); -- 2, 4, 5, 6, 3 cbl1Half0M : inout slv(4 downto 0); -- 15, 17, 18, 19 16 @@ -49,8 +52,8 @@ entity ClinkTop is cbl1Half1P : inout slv(4 downto 0); -- 8, 10, 11, 12, 9 cbl1Half1M : inout slv(4 downto 0); -- 21, 23, 24, 25, 22 -- Connector 1, Serial out - cbl1SerP : out sl; -- 20 - cbl1SerM : out sl; -- 7 + cbl1SerP : out sl; -- 20 + cbl1SerM : out sl; -- 7 -- Delay clock and reset, 200Mhz dlyClk : in sl; dlyRst : in sl; @@ -84,38 +87,33 @@ end ClinkTop; architecture rtl of ClinkTop is - type RegType is record - locked : slv(2 downto 0); - lockCnt : Slv8Array(2 downto 0); - chanConfig : ClChanConfigArray(1 downto 0); - linkConfig : ClLinkConfigType; - axilReadSlave : AxiLiteReadSlaveType; - axilWriteSlave : AxiLiteWriteSlaveType; - end record RegType; - - constant REG_INIT_C : RegType := ( - locked => "000", - lockCnt => (others=>x"00"), - chanConfig => (others => CL_CHAN_CONFIG_INIT_C), - linkConfig => CL_LINK_CONFIG_INIT_C, - axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, - axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal chanStatus : ClChanStatusArray(1 downto 0); - signal linkStatus : ClLinkStatusArray(2 downto 0); - signal parData : Slv28Array(2 downto 0); - signal parValid : slv(2 downto 0); - signal frameReady : slv(1 downto 0); + constant NUM_AXIL_MASTERS_C : natural := 4; + + constant MAIN_INDEX_C : natural := 0; + constant DRP0_INDEX_C : natural := 1; + constant DRP1_INDEX_C : natural := 2; + constant DRP2_INDEX_C : natural := 3; + + constant XBAR_CONFIG_C : AxiLiteCrossbarMasterConfigArray(NUM_AXIL_MASTERS_C-1 downto 0) := genAxiLiteConfig(NUM_AXIL_MASTERS_C, AXIL_BASE_ADDR_G, 14, 12); + signal intReadMaster : AxiLiteReadMasterType; signal intReadSlave : AxiLiteReadSlaveType; signal intWriteMaster : AxiLiteWriteMasterType; signal intWriteSlave : AxiLiteWriteSlaveType; - --attribute MARK_DEBUG : string; - --attribute MARK_DEBUG of r : signal is "TRUE"; + signal axilWriteMasters : AxiLiteWriteMasterArray(NUM_AXIL_MASTERS_C-1 downto 0); + signal axilWriteSlaves : AxiLiteWriteSlaveArray(NUM_AXIL_MASTERS_C-1 downto 0); + signal axilReadMasters : AxiLiteReadMasterArray(NUM_AXIL_MASTERS_C-1 downto 0); + signal axilReadSlaves : AxiLiteReadSlaveArray(NUM_AXIL_MASTERS_C-1 downto 0); + + signal chanConfig : ClChanConfigArray(1 downto 0); + signal linkConfig : ClLinkConfigType; + signal chanStatus : ClChanStatusArray(1 downto 0) := (others => CL_CHAN_STATUS_INIT_C); + signal linkStatus : ClLinkStatusArray(2 downto 0) := (others => CL_LINK_STATUS_INIT_C); + signal parData : Slv28Array(2 downto 0); + signal parValid : slv(2 downto 0); + signal frameReady : slv(1 downto 0); + attribute IODELAY_GROUP : string; attribute IODELAY_GROUP of U_IDelayCtrl : label is "CLINK_CORE"; @@ -124,16 +122,80 @@ begin camStatus <= chanStatus; - ---------------------------------------- - -- IO Modules - ---------------------------------------- + --------------------- + -- IDELAYCTRL Modules + --------------------- U_IdelayCtrl : IDELAYCTRL port map ( RDY => open, -- 1-bit output: Ready output REFCLK => dlyClk, -- 1-bit input: Reference clock input RST => dlyRst); -- 1-bit input: Active high reset input + ---------------------------- + -- AXI-Lite Clock Transition + ---------------------------- + U_AxilAsync : entity work.AxiLiteAsync + generic map ( + TPD_G => TPD_G, + COMMON_CLK_G => COMMON_AXIL_CLK_G) + port map ( + sAxiClk => axilClk, + sAxiClkRst => axilRst, + sAxiReadMaster => axilReadMaster, + sAxiReadSlave => axilReadSlave, + sAxiWriteMaster => axilWriteMaster, + sAxiWriteSlave => axilWriteSlave, + mAxiClk => sysClk, + mAxiClkRst => sysRst, + mAxiReadMaster => intReadMaster, + mAxiReadSlave => intReadSlave, + mAxiWriteMaster => intWriteMaster, + mAxiWriteSlave => intWriteSlave); + + -------------------------- + -- AXI-Lite: Crossbar Core + -------------------------- + U_XBAR : entity work.AxiLiteCrossbar + generic map ( + TPD_G => TPD_G, + NUM_SLAVE_SLOTS_G => 1, + NUM_MASTER_SLOTS_G => NUM_AXIL_MASTERS_C, + MASTERS_CONFIG_G => XBAR_CONFIG_C) + port map ( + axiClk => sysClk, + axiClkRst => sysRst, + sAxiWriteMasters(0) => intWriteMaster, + sAxiWriteSlaves(0) => intWriteSlave, + sAxiReadMasters(0) => intReadMaster, + sAxiReadSlaves(0) => intReadSlave, + mAxiWriteMasters => axilWriteMasters, + mAxiWriteSlaves => axilWriteSlaves, + mAxiReadMasters => axilReadMasters, + mAxiReadSlaves => axilReadSlaves); + + --------------------------- + -- AXI-Lite Register Module + --------------------------- + U_ClinkReg : entity work.ClinkReg + generic map ( + TPD_G => TPD_G, + CHAN_COUNT_G => CHAN_COUNT_G) + port map ( + chanStatus => chanStatus, + linkStatus => linkStatus, + chanConfig => chanConfig, + linkConfig => linkConfig, + -- Axi-Lite Interface + sysClk => sysClk, + sysRst => sysRst, + axilReadMaster => axilReadMasters(MAIN_INDEX_C), + axilReadSlave => axilReadSlaves(MAIN_INDEX_C), + axilWriteMaster => axilWriteMasters(MAIN_INDEX_C), + axilWriteSlave => axilWriteSlaves(MAIN_INDEX_C)); + + --------------------------------------------------------- -- Connector 0, Half 0, Control for Base,Medium,Full,Deca + --------------------------------------------------------- U_Cbl0Half0 : entity work.ClinkCtrl generic map ( TPD_G => TPD_G, @@ -150,7 +212,7 @@ begin sysClk => sysClk, sysRst => sysRst, camCtrl => camCtrl(0), - chanConfig => r.chanConfig(0), + chanConfig => chanConfig(0), uartClk => uartClk, uartRst => uartRst, sUartMaster => sUartMasters(0), @@ -159,26 +221,37 @@ begin mUartMaster => mUartMasters(0), mUartSlave => mUartSlaves(0)); + -------------------------------------------------------- -- Connector 0, Half 1, Data X for Base,Medium,Full,Deca + -------------------------------------------------------- U_Cbl0Half1 : entity work.ClinkData generic map (TPD_G => TPD_G) port map ( - cblHalfP => cbl0Half1P, - cblHalfM => cbl0Half1M, - dlyClk => dlyClk, - dlyRst => dlyRst, - sysClk => sysClk, - sysRst => sysRst, - linkConfig => r.linkConfig, - linkStatus => linkStatus(0), - parData => parData(0), - parValid => parValid(0), - parReady => frameReady(0)); - + cblHalfP => cbl0Half1P, + cblHalfM => cbl0Half1M, + dlyClk => dlyClk, + dlyRst => dlyRst, + sysClk => sysClk, + sysRst => sysRst, + linkConfig => linkConfig, + linkStatus => linkStatus(0), + parData => parData(0), + parValid => parValid(0), + parReady => frameReady(0), + -- AXI-Lite Interface + axilReadMaster => axilReadMasters(DRP0_INDEX_C), + axilReadSlave => axilReadSlaves(DRP0_INDEX_C), + axilWriteMaster => axilWriteMasters(DRP0_INDEX_C), + axilWriteSlave => axilWriteSlaves(DRP0_INDEX_C)); + + ---------------------- -- Dual channel enable - U_DualCtrlEn : if CHAN_COUNT_G = 2 generate + ---------------------- + U_DualCtrlEn : if (CHAN_COUNT_G = 2) generate + ---------------------------------------------------------------- -- Connector 1, Half 0, Control Base, Data Z for Med, Full, Deca + ---------------------------------------------------------------- U_Cbl1Half0 : entity work.ClinkCtrl generic map ( TPD_G => TPD_G, @@ -195,7 +268,7 @@ begin sysClk => sysClk, sysRst => sysRst, camCtrl => camCtrl(1), - chanConfig => r.chanConfig(1), + chanConfig => chanConfig(1), uartClk => uartClk, uartRst => uartRst, sUartMaster => sUartMasters(1), @@ -204,32 +277,59 @@ begin mUartMaster => mUartMasters(1), mUartSlave => mUartSlaves(1)); + ----------------- -- Unused signals + ----------------- linkStatus(2) <= CL_LINK_STATUS_INIT_C; parData(2) <= (others => '0'); parValid(2) <= '0'; + U_UnusedDrp : entity work.AxiDualPortRam + generic map ( + TPD_G => TPD_G, + ADDR_WIDTH_G => 7, + DATA_WIDTH_G => 16) + port map ( + -- AXI-Lite Interface + axiClk => sysClk, + axiRst => sysRst, + axiReadMaster => axilReadMasters(DRP2_INDEX_C), + axiReadSlave => axilReadSlaves(DRP2_INDEX_C), + axiWriteMaster => axilWriteMasters(DRP2_INDEX_C), + axiWriteSlave => axilWriteSlaves(DRP2_INDEX_C)); end generate; + ----------------------- -- Dual channel disable - U_DualCtrlDis : if CHAN_COUNT_G = 1 generate + ----------------------- + U_DualCtrlDis : if (CHAN_COUNT_G = 1) generate + ---------------------------------------------------------------- -- Connector 1, Half 0, Control Base, Data Z for Med, Full, Deca + ---------------------------------------------------------------- U_Cbl1Half0 : entity work.ClinkData generic map (TPD_G => TPD_G) port map ( - cblHalfP => cbl1Half0P, - cblHalfM => cbl1Half0M, - dlyClk => dlyClk, - dlyRst => dlyRst, - sysClk => sysClk, - sysRst => sysRst, - linkConfig => r.linkConfig, - linkStatus => linkStatus(2), - parData => parData(2), - parValid => parValid(2), - parReady => frameReady(0)); - + cblHalfP => cbl1Half0P, + cblHalfM => cbl1Half0M, + dlyClk => dlyClk, + dlyRst => dlyRst, + sysClk => sysClk, + sysRst => sysRst, + linkConfig => linkConfig, + linkStatus => linkStatus(2), + parData => parData(2), + parValid => parValid(2), + parReady => frameReady(0), + -- AXI-Lite Interface + axilReadMaster => axilReadMasters(DRP2_INDEX_C), + axilReadSlave => axilReadSlaves(DRP2_INDEX_C), + axilWriteMaster => axilWriteMasters(DRP2_INDEX_C), + axilWriteSlave => axilWriteSlaves(DRP2_INDEX_C)); + + ----------------- + -- Unused signals + ----------------- U_SerOut : OBUFDS port map ( I => '0', @@ -238,33 +338,41 @@ begin end generate; + ------------------------------------------------------------------- -- Connector 1, Half 1, Data X for Base, Data Y for Med, Full, Deca + ------------------------------------------------------------------- U_Cbl1Half1 : entity work.ClinkData generic map (TPD_G => TPD_G) port map ( - cblHalfP => cbl1Half1P, - cblHalfM => cbl1Half1M, - dlyClk => dlyClk, - dlyRst => dlyRst, - sysClk => sysClk, - sysRst => sysRst, - linkConfig => r.linkConfig, - linkStatus => linkStatus(1), - parData => parData(1), - parValid => parValid(1), - parReady => frameReady(1)); - - --------------------------------- + cblHalfP => cbl1Half1P, + cblHalfM => cbl1Half1M, + dlyClk => dlyClk, + dlyRst => dlyRst, + sysClk => sysClk, + sysRst => sysRst, + linkConfig => linkConfig, + linkStatus => linkStatus(1), + parData => parData(1), + parValid => parValid(1), + parReady => frameReady(1), + -- AXI-Lite Interface + axilReadMaster => axilReadMasters(DRP1_INDEX_C), + axilReadSlave => axilReadSlaves(DRP1_INDEX_C), + axilWriteMaster => axilWriteMasters(DRP1_INDEX_C), + axilWriteSlave => axilWriteSlaves(DRP1_INDEX_C)); + + ------------------ -- Data Processing - --------------------------------- + ------------------ U_Framer0 : entity work.ClinkFraming generic map ( TPD_G => TPD_G, + COMMON_DATA_CLK_G => COMMON_DATA_CLK_G, DATA_AXIS_CONFIG_G => DATA_AXIS_CONFIG_G) port map ( sysClk => sysClk, sysRst => sysRst, - chanConfig => r.chanConfig(0), + chanConfig => chanConfig(0), chanStatus => chanStatus(0), linkStatus => linkStatus, parData => parData, @@ -275,17 +383,20 @@ begin dataMaster => dataMasters(0), dataSlave => dataSlaves(0)); + ------------------------------ -- Dual data processing enable - U_DualFrameEn : if CHAN_COUNT_G = 2 generate + ------------------------------ + U_DualFrameEn : if (CHAN_COUNT_G = 2) generate U_Framer1 : entity work.ClinkFraming generic map ( TPD_G => TPD_G, + COMMON_DATA_CLK_G => COMMON_DATA_CLK_G, DATA_AXIS_CONFIG_G => DATA_AXIS_CONFIG_G) port map ( sysClk => sysClk, sysRst => sysRst, - chanConfig => r.chanConfig(1), + chanConfig => chanConfig(1), chanStatus => chanStatus(1), linkStatus(0) => linkStatus(1), linkStatus(1) => CL_LINK_STATUS_INIT_C, @@ -304,157 +415,12 @@ begin end generate; + ------------------------------- -- Dual data processing disable + ------------------------------- U_DualFrameDis : if CHAN_COUNT_G = 1 generate chanStatus(1) <= CL_CHAN_STATUS_INIT_C; frameReady(1) <= frameReady(0); end generate; - --------------------------------- - -- AXIL Clock Transition - --------------------------------- - U_AxilAsync : entity work.AxiLiteAsync - generic map ( - TPD_G => TPD_G, - COMMON_CLK_G => false) - port map ( - sAxiClk => axilClk, - sAxiClkRst => axilRst, - sAxiReadMaster => axilReadMaster, - sAxiReadSlave => axilReadSlave, - sAxiWriteMaster => axilWriteMaster, - sAxiWriteSlave => axilWriteSlave, - mAxiClk => sysClk, - mAxiClkRst => sysRst, - mAxiReadMaster => intReadMaster, - mAxiReadSlave => intReadSlave, - mAxiWriteMaster => intWriteMaster, - mAxiWriteSlave => intWriteSlave); - - --------------------------------- - -- Registers - --------------------------------- - comb : process (chanStatus, intReadMaster, intWriteMaster, linkStatus, r, - sysRst) is - - variable v : RegType; - variable axilEp : AxiLiteEndpointType; - variable i : natural; - begin - - -- Latch the current value - v := r; - - -- Loop through the locking channels - for i in 2 downto 0 loop - -- Keep delayed copy of the locks - v.locked(i) := linkStatus(i).locked; - -- Check for 0->1 lock transition and not max value - if (r.locked(i) = '0') and (linkStatus(i).locked = '1') and (r.lockCnt(i) /= x"FF") then - -- Increment the counter - v.lockCnt(i) := r.lockCnt(i) + 1; - end if; - end loop; - - -- Check for counter reset - if (r.linkConfig.cntRst = '1') then - v.lockCnt := (others=>x"00"); - end if; - - ------------------------ - -- AXI-Lite Transactions - ------------------------ - - -- Determine the transaction type - axiSlaveWaitTxn(axilEp, intWriteMaster, intReadMaster, v.axilWriteSlave, v.axilReadSlave); - - -- Common Config - axiSlaveRegisterR(axilEp, x"000", 0, toSlv(CHAN_COUNT_G, 4)); - axiSlaveRegister (axilEp, x"004", 0, v.linkConfig.rstPll); - axiSlaveRegister (axilEp, x"004", 1, v.linkConfig.rstFsm); - axiSlaveRegister (axilEp, x"004", 2, v.linkConfig.cntRst); - - -- Common Status - axiSlaveRegisterR(axilEp, x"010", 0, linkStatus(0).locked); - axiSlaveRegisterR(axilEp, x"010", 1, linkStatus(1).locked); - axiSlaveRegisterR(axilEp, x"010", 2, linkStatus(2).locked); - axiSlaveRegisterR(axilEp, x"010", 8, r.lockCnt(0)); - axiSlaveRegisterR(axilEp, x"010", 16, r.lockCnt(1)); - axiSlaveRegisterR(axilEp, x"010", 24, r.lockCnt(2)); - axiSlaveRegisterR(axilEp, x"014", 0, linkStatus(0).shiftCnt); - axiSlaveRegisterR(axilEp, x"014", 8, linkStatus(1).shiftCnt); - axiSlaveRegisterR(axilEp, x"014", 16, linkStatus(2).shiftCnt); - axiSlaveRegisterR(axilEp, x"018", 0, linkStatus(0).delay); - axiSlaveRegisterR(axilEp, x"018", 8, linkStatus(1).delay); - axiSlaveRegisterR(axilEp, x"018", 16, linkStatus(2).delay); - - -- Channel A Config - axiSlaveRegister (axilEp, x"100", 0, v.chanConfig(0).linkMode); - axiSlaveRegister (axilEp, x"104", 0, v.chanConfig(0).dataMode); - axiSlaveRegister (axilEp, x"108", 0, v.chanConfig(0).frameMode); - axiSlaveRegister (axilEp, x"10C", 0, v.chanConfig(0).tapCount); - axiSlaveRegister (axilEp, x"110", 0, v.chanConfig(0).dataEn); - axiSlaveRegister (axilEp, x"110", 1, v.chanConfig(0).blowoff); - axiSlaveRegister (axilEp, x"110", 2, v.chanConfig(0).cntRst); - axiSlaveRegister (axilEp, x"110", 16, v.chanConfig(0).serThrottle); - axiSlaveRegister (axilEp, x"114", 0, v.chanConfig(0).serBaud); - axiSlaveRegister (axilEp, x"118", 0, v.chanConfig(0).swCamCtrlEn); - axiSlaveRegister (axilEp, x"11C", 0, v.chanConfig(0).swCamCtrl); - - -- Channel A Status - axiSlaveRegisterR(axilEp, x"120", 0, chanStatus(0).running); - axiSlaveRegisterR(axilEp, x"124", 0, chanStatus(0).frameCount); - axiSlaveRegisterR(axilEp, x"128", 0, chanStatus(0).dropCount); - - -- Channel B Config - axiSlaveRegister (axilEp, x"200", 0, v.chanConfig(1).linkMode); - axiSlaveRegister (axilEp, x"204", 0, v.chanConfig(1).dataMode); - axiSlaveRegister (axilEp, x"208", 0, v.chanConfig(1).frameMode); - axiSlaveRegister (axilEp, x"20C", 0, v.chanConfig(1).tapCount); - axiSlaveRegister (axilEp, x"210", 0, v.chanConfig(1).dataEn); - axiSlaveRegister (axilEp, x"210", 1, v.chanConfig(1).blowoff); - axiSlaveRegister (axilEp, x"210", 2, v.chanConfig(1).cntRst); - axiSlaveRegister (axilEp, x"210", 16, v.chanConfig(1).serThrottle); - axiSlaveRegister (axilEp, x"214", 0, v.chanConfig(1).serBaud); - axiSlaveRegister (axilEp, x"218", 0, v.chanConfig(1).swCamCtrlEn); - axiSlaveRegister (axilEp, x"21C", 0, v.chanConfig(1).swCamCtrl); - - -- Channel B Status - axiSlaveRegisterR(axilEp, x"220", 0, chanStatus(1).running); - axiSlaveRegisterR(axilEp, x"224", 0, chanStatus(1).frameCount); - axiSlaveRegisterR(axilEp, x"228", 0, chanStatus(1).dropCount); - - axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); - - -- Prevent zero baud rate - if (v.chanConfig(0).serBaud = 0) then - v.chanConfig(0).serBaud := toSlv(1, 24); - end if; - if (v.chanConfig(1).serBaud = 0) then - v.chanConfig(1).serBaud := toSlv(1, 24); - end if; - - ------------- - -- Reset - ------------- - if (sysRst = '1') then - v := REG_INIT_C; - end if; - - -- Register the variable for next clock cycle - rin <= v; - - -- Outputs - intReadSlave <= r.axilReadSlave; - intWriteSlave <= r.axilWriteSlave; - - end process comb; - - seq : process (sysClk) is - begin - if (rising_edge(sysClk)) then - r <= rin after TPD_G; - end if; - end process seq; - end rtl; diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index f7c62e6cdd..82a1443628 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -135,6 +135,7 @@ def __init__( self, disp = '{}', mode = "RW", units = "bps", + value = 9600, )) self.add(pr.RemoteVariable( @@ -192,37 +193,55 @@ def __init__( self, self._rx = None self._tx = None - + # Check if serial interface defined if serial is not None: + # Check for OPA1000 camera - if (camType=='Opal000'): + if (camType is 'Opal000'): + + # Add the device self.add(cl.UartOpal000( name = 'UartOpal000', serial = serial, expand = False, - )) + )) + + # Override default baud rate + self.BaudRate._default = 57600 + # Check for Piranha4 camera - elif (camType=='Piranha4'): + elif (camType is 'Piranha4'): + + # Add the device self.add(cl.UartPiranha4( name = 'UartPiranha4', serial = serial, expand = False, - )) + )) + # Check for Uniq UP-900CL-12B camera - elif (camType=='UartUp900cl12b'): + elif (camType is 'UartUp900cl12b'): + + # Add the device self.add(cl.UartPiranha4( name = 'UartUp900cl12b', serial = serial, expand = False, )) + # Else generic interface to serial stream - else: + elif camType is None: + + # Add the device self.add(cl.UartGeneric( name = 'UartGeneric', serial = serial, expand = False, - )) + )) + + else: + raise ValueError('Invalid camType (%s)' % (camType) ) ############################################################################## def hardReset(self): diff --git a/python/surf/protocols/clink/_ClinkTop.py b/python/surf/protocols/clink/_ClinkTop.py index d356210654..3c166b06b0 100644 --- a/python/surf/protocols/clink/_ClinkTop.py +++ b/python/surf/protocols/clink/_ClinkTop.py @@ -19,6 +19,7 @@ import pyrogue as pr import surf.protocols.clink as cl +import surf.xilinx as xil class ClinkTop(pr.Device): def __init__( self, @@ -194,6 +195,48 @@ def __init__( self, mode = "RO", pollInterval = 1, )) + + self.addRemoteVariables( + name = "ClkInFreq", + description = "Clock Input Freq", + offset = 0x01C, + bitSize = 32, + bitOffset = 0, + units = 'Hz', + disp = '{:d}', + mode = "RO", + pollInterval = 1, + number = 3, + stride = 4, + ) + + self.addRemoteVariables( + name = "ClinkClkFreq", + description = "CameraLink Clock Freq", + offset = 0x028, + bitSize = 32, + bitOffset = 0, + units = 'Hz', + disp = '{:d}', + mode = "RO", + pollInterval = 1, + number = 3, + stride = 4, + ) + + self.addRemoteVariables( + name = "ClinkClk7xFreq", + description = "CameraLink Clock x 7 Freq", + offset = 0x034, + bitSize = 32, + bitOffset = 0, + units = 'Hz', + disp = '{:d}', + mode = "RO", + pollInterval = 1, + number = 3, + stride = 4, + ) for i in range(2): if serial[i] is not None: @@ -204,7 +247,14 @@ def __init__( self, camType = camType[i], # expand = False, )) - + for i in range(3): + self.add(xil.ClockManager( + name = f'Pll[{i}]', + offset = 0x1000+(i*0x1000), + type = 'MMCME2', + expand = False, + )) + def hardReset(self): self.CntRst() From f3a392c8ef5a2c1285f464568fecc13b74497164 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Mar 2019 17:14:00 -0700 Subject: [PATCH 58/92] remove the Clk7x freq measurement --- protocols/clink/hdl/ClinkData.vhd | 1 - protocols/clink/hdl/ClinkDataShift.vhd | 15 --------------- protocols/clink/hdl/ClinkPkg.vhd | 2 -- protocols/clink/hdl/ClinkReg.vhd | 4 ---- python/surf/protocols/clink/_ClinkChannel.py | 6 +++--- python/surf/protocols/clink/_ClinkTop.py | 16 +--------------- 6 files changed, 4 insertions(+), 40 deletions(-) diff --git a/protocols/clink/hdl/ClinkData.vhd b/protocols/clink/hdl/ClinkData.vhd index 8c8a9ea343..338837ba48 100644 --- a/protocols/clink/hdl/ClinkData.vhd +++ b/protocols/clink/hdl/ClinkData.vhd @@ -120,7 +120,6 @@ begin -- Frequency Measurements clkInFreq => linkStatus.clkInFreq, clinkClkFreq => linkStatus.clinkClkFreq, - clinkClk7xFreq => linkStatus.clinkClk7xFreq, -- AXI-Lite Interface sysClk => sysClk, sysRst => sysRst, diff --git a/protocols/clink/hdl/ClinkDataShift.vhd b/protocols/clink/hdl/ClinkDataShift.vhd index b2f3b31650..366fb3c353 100644 --- a/protocols/clink/hdl/ClinkDataShift.vhd +++ b/protocols/clink/hdl/ClinkDataShift.vhd @@ -52,7 +52,6 @@ entity ClinkDataShift is -- Frequency Measurements clkInFreq : out slv(31 downto 0); clinkClkFreq : out slv(31 downto 0); - clinkClk7xFreq : out slv(31 downto 0); -- AXI-Lite Interface sysClk : in sl; sysRst : in sl; @@ -108,20 +107,6 @@ begin locClk => sysClk, refClk => dlyClk); - U_clinkClk7xFreq : entity work.SyncClockFreq - generic map ( - TPD_G => TPD_G, - REF_CLK_FREQ_G => 200.0E+6, - REFRESH_RATE_G => 1.0, - CNT_WIDTH_G => 32) - port map ( - -- Frequency Measurement (locClk domain) - freqOut => clinkClk7xFreq, - -- Clocks - clkIn => intClk7x, - locClk => sysClk, - refClk => dlyClk); - -------------------------------------- -- Clock Generation -------------------------------------- diff --git a/protocols/clink/hdl/ClinkPkg.vhd b/protocols/clink/hdl/ClinkPkg.vhd index 041969b619..aa5e95929e 100644 --- a/protocols/clink/hdl/ClinkPkg.vhd +++ b/protocols/clink/hdl/ClinkPkg.vhd @@ -73,7 +73,6 @@ package ClinkPkg is type ClLinkStatusType is record clkInFreq : slv(31 downto 0); clinkClkFreq : slv(31 downto 0); - clinkClk7xFreq : slv(31 downto 0); locked : sl; delay : slv(4 downto 0); shiftCnt : slv(2 downto 0); @@ -82,7 +81,6 @@ package ClinkPkg is constant CL_LINK_STATUS_INIT_C : ClLinkStatusType := ( clkInFreq => (others => '0'), clinkClkFreq => (others => '0'), - clinkClk7xFreq => (others => '0'), locked => '0', delay => (others => '0'), shiftCnt => (others => '0')); diff --git a/protocols/clink/hdl/ClinkReg.vhd b/protocols/clink/hdl/ClinkReg.vhd index 4ee7f529f6..7488bf4925 100644 --- a/protocols/clink/hdl/ClinkReg.vhd +++ b/protocols/clink/hdl/ClinkReg.vhd @@ -132,10 +132,6 @@ begin axiSlaveRegisterR(axilEp, x"02C", 0, linkStatus(1).clinkClkFreq); axiSlaveRegisterR(axilEp, x"030", 0, linkStatus(2).clinkClkFreq); - axiSlaveRegisterR(axilEp, x"034", 0, linkStatus(0).clinkClk7xFreq); - axiSlaveRegisterR(axilEp, x"038", 0, linkStatus(1).clinkClk7xFreq); - axiSlaveRegisterR(axilEp, x"03C", 0, linkStatus(2).clinkClk7xFreq); - -- Channel A Config axiSlaveRegister (axilEp, x"100", 0, v.chanConfig(0).linkMode); axiSlaveRegister (axilEp, x"104", 0, v.chanConfig(0).dataMode); diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index 82a1443628..c098b53b32 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -198,7 +198,7 @@ def __init__( self, if serial is not None: # Check for OPA1000 camera - if (camType is 'Opal000'): + if (camType=='Opal000'): # Add the device self.add(cl.UartOpal000( @@ -211,7 +211,7 @@ def __init__( self, self.BaudRate._default = 57600 # Check for Piranha4 camera - elif (camType is 'Piranha4'): + elif (camType=='Piranha4'): # Add the device self.add(cl.UartPiranha4( @@ -221,7 +221,7 @@ def __init__( self, )) # Check for Uniq UP-900CL-12B camera - elif (camType is 'UartUp900cl12b'): + elif (camType=='Up900cl12b'): # Add the device self.add(cl.UartPiranha4( diff --git a/python/surf/protocols/clink/_ClinkTop.py b/python/surf/protocols/clink/_ClinkTop.py index 3c166b06b0..9cb4e86f1e 100644 --- a/python/surf/protocols/clink/_ClinkTop.py +++ b/python/surf/protocols/clink/_ClinkTop.py @@ -223,21 +223,7 @@ def __init__( self, number = 3, stride = 4, ) - - self.addRemoteVariables( - name = "ClinkClk7xFreq", - description = "CameraLink Clock x 7 Freq", - offset = 0x034, - bitSize = 32, - bitOffset = 0, - units = 'Hz', - disp = '{:d}', - mode = "RO", - pollInterval = 1, - number = 3, - stride = 4, - ) - + for i in range(2): if serial[i] is not None: self.add(cl.ClinkChannel( From fe56888da8cbb293da8588f74628cd4b02cad440 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 26 Mar 2019 18:10:57 -0700 Subject: [PATCH 59/92] backing up progress on UartUp900cl12b.py --- protocols/clink/hdl/ClinkDataClk.vhd | 13 ++++++---- python/surf/protocols/clink/_ClinkChannel.py | 2 +- .../surf/protocols/clink/_UartUp900cl12b.py | 24 ++++++++++++++++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/protocols/clink/hdl/ClinkDataClk.vhd b/protocols/clink/hdl/ClinkDataClk.vhd index 8e73d383d5..c379aefeee 100644 --- a/protocols/clink/hdl/ClinkDataClk.vhd +++ b/protocols/clink/hdl/ClinkDataClk.vhd @@ -94,11 +94,16 @@ begin BANDWIDTH => "OPTIMIZED", CLKOUT4_CASCADE => false, STARTUP_WAIT => false, - CLKIN1_PERIOD => 11.764, -- 85Mhz +-- CLKIN1_PERIOD => 40.0, -- 25 MHz +-- DIVCLK_DIVIDE => 1, +-- CLKFBOUT_MULT_F => 42.0, -- VCO = 1050MHz +-- CLKOUT0_DIVIDE_F => 42.0, -- 25 MHz +-- CLKOUT1_DIVIDE => 6) -- 175MHz + CLKIN1_PERIOD => 11.764, -- 85 MHz (CLKIN[min.] = 43 MHz, CLKIN[max] = 102 MHz) DIVCLK_DIVIDE => 1, - CLKFBOUT_MULT_F => 14.0, -- 1190Mhz - CLKOUT0_DIVIDE_F => 14.0, -- 85Mhz - CLKOUT1_DIVIDE => 2) -- 595Mhz + CLKFBOUT_MULT_F => 14.0, -- VCO = 1190MHz (VCO[min] = 600 MHz, VCO[max] = 1440 MHz) + CLKOUT0_DIVIDE_F => 14.0, -- 85 MHz = 1190MHz/14 + CLKOUT1_DIVIDE => 2) -- 595MHz = 1190MHz/2 port map ( DCLK => sysClk, DRDY => drpRdy, diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index c098b53b32..da26ccf734 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -224,7 +224,7 @@ def __init__( self, elif (camType=='Up900cl12b'): # Add the device - self.add(cl.UartPiranha4( + self.add(cl.UartUp900cl12b( name = 'UartUp900cl12b', serial = serial, expand = False, diff --git a/python/surf/protocols/clink/_UartUp900cl12b.py b/python/surf/protocols/clink/_UartUp900cl12b.py index 0bdeef8121..8c60f0dc88 100644 --- a/python/surf/protocols/clink/_UartUp900cl12b.py +++ b/python/surf/protocols/clink/_UartUp900cl12b.py @@ -21,17 +21,35 @@ import rogue.interfaces.stream import surf.protocols.clink as clink + +class UartUp900cl12bRx(clink.ClinkSerialRx): + def __init__(self,**kwargs): + super().__init__(**kwargs) + + def _acceptFrame(self,frame): + ba = bytearray(frame.getPayload()) + frame.read(ba,0) + + for i in range(0,len(ba),4): + c = chr(ba[i]) + # print (ba[i]) + + if (c == '\r'): + print("Got Response: {}".format(''.join(self._cur))) + self._cur = [] + elif (c != '') and (ba[i] != 1): + self._cur.append(c) class UartUp900cl12b(pr.Device): def __init__( self, name = 'UartUp900cl12b', - description = 'Uart Uniq UP-900CL-12B channel access', + description = 'Uart Uniq UP-900CL-12B channel access (http://uniqvision.com/Downloads/UP900CL-12B)', serial = None, **kwargs): super().__init__(name=name, description=description, **kwargs) # Attach the serial devices - self._rx = clink.ClinkSerialRx() + self._rx = clink.UartUp900cl12bRx() pr.streamConnect(serial,self._rx) self._tx = clink.ClinkSerialTx() @@ -41,7 +59,7 @@ def __init__( self, def sendString(arg): if self._tx is not None: self._tx.sendString(arg) - + ############################## # Variables ############################## From b6ce69de8a24eaca20b85ee617b1d9f3628991b6 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 27 Mar 2019 08:32:01 -0700 Subject: [PATCH 60/92] py reorg --- python/surf/axi/__init__.py | 1 - .../batcher}/_AxiStreamBatcherEventBuilder.py | 0 python/surf/protocols/batcher/__init__.py | 3 ++- 3 files changed, 2 insertions(+), 2 deletions(-) rename python/surf/{axi => protocols/batcher}/_AxiStreamBatcherEventBuilder.py (100%) diff --git a/python/surf/axi/__init__.py b/python/surf/axi/__init__.py index 9fc7aed71a..c35d4c399f 100644 --- a/python/surf/axi/__init__.py +++ b/python/surf/axi/__init__.py @@ -10,7 +10,6 @@ ############################################################################## from surf.axi._AxiLiteEmpty import * from surf.axi._AxiMemTester import * -from surf.axi._AxiStreamBatcherEventBuilder import * from surf.axi._AxiStreamDmaRingWrite import * from surf.axi._AxiStreamMonitoring import * from surf.axi._AxiVersion import * diff --git a/python/surf/axi/_AxiStreamBatcherEventBuilder.py b/python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py similarity index 100% rename from python/surf/axi/_AxiStreamBatcherEventBuilder.py rename to python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py diff --git a/python/surf/protocols/batcher/__init__.py b/python/surf/protocols/batcher/__init__.py index c1424fb8e1..eeab102755 100644 --- a/python/surf/protocols/batcher/__init__.py +++ b/python/surf/protocols/batcher/__init__.py @@ -1 +1,2 @@ -from surf.protocols.batcher._AxiStreamBatcherAxil import * +from surf.protocols.batcher._AxiStreamBatcherAxil import * +from surf.protocols.batcher._AxiStreamBatcherEventBuilder import * From 32722961c1df10be3e5f1489da0a41212da7c468 Mon Sep 17 00:00:00 2001 From: Mitch D'Ewart Date: Wed, 27 Mar 2019 12:43:06 -0700 Subject: [PATCH 61/92] Add SHADOW_EN_G generic to AxiSpiMaster If enabled will generate a single port RAM to shadow the SPI device memory - writes go to SPI and shadow memory - reads return shadow memory --- protocols/spi/rtl/AxiSpiMaster.vhd | 48 ++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/protocols/spi/rtl/AxiSpiMaster.vhd b/protocols/spi/rtl/AxiSpiMaster.vhd index 42776fbcda..632aa5d083 100644 --- a/protocols/spi/rtl/AxiSpiMaster.vhd +++ b/protocols/spi/rtl/AxiSpiMaster.vhd @@ -39,6 +39,7 @@ entity AxiSpiMaster is ADDRESS_SIZE_G : natural := 15; DATA_SIZE_G : natural := 8; MODE_G : string := "RW"; -- Or "WO" (write only), "RO" (read only) + SHADOW_EN_G : boolean := false; CPHA_G : sl := '0'; CPOL_G : sl := '0'; CLK_PERIOD_G : real := 6.4E-9; @@ -71,7 +72,14 @@ architecture rtl of AxiSpiMaster is signal rdData : slv(PACKET_SIZE_C-1 downto 0); signal rdEn : sl; - type StateType is (WAIT_AXI_TXN_S, WAIT_CYCLE_S, WAIT_SPI_TXN_DONE_S); + type StateType is (WAIT_AXI_TXN_S, WAIT_CYCLE_S, WAIT_CYCLE_SHADOW_S, WAIT_SPI_TXN_DONE_S); + + + type mem_type is array ((2**ADDRESS_SIZE_G)-1 downto 0) of slv(DATA_SIZE_G-1 downto 0); + signal mem : mem_type := (others => (others => '0')); + signal memData : slv(DATA_SIZE_G-1 downto 0) := (others => '0'); + signal memAddr : slv(ADDRESS_SIZE_G-1 downto 0) := (others => '0'); + signal memWe : sl := '0'; -- Registers type RegType is record @@ -98,7 +106,11 @@ architecture rtl of AxiSpiMaster is begin - comb : process (axiReadMaster, axiRst, axiWriteMaster, r, rdData, rdEn) is + + memAddr <= r.wrData(DATA_SIZE_G+ADDRESS_SIZE_G-1 downto DATA_SIZE_G); + memWe <= r.wrEn; + + comb : process (axiReadMaster, axiRst, axiWriteMaster, r, rdData, rdEn, memData) is variable v : RegType; variable axiStatus : AxiLiteStatusType; begin @@ -113,7 +125,6 @@ begin if (MODE_G = "RO") then axiSlaveWriteResponse(v.axiWriteSlave, AXI_RESP_DECERR_C); else - -- No write bit when mode is write-only if (MODE_G /= "WO") then v.wrData(PACKET_SIZE_C-1) := '0'; @@ -135,13 +146,18 @@ begin if (axiStatus.readEnable = '1') then if (MODE_G = "WO") then axiSlaveReadResponse(v.axiReadSlave, AXI_RESP_DECERR_C); + elsif (SHADOW_EN_G) then + v.state := WAIT_CYCLE_SHADOW_S; -- just go to wait a cycle for memData to update + v.wrData(PACKET_SIZE_C-1) := '1'; -- indicate axi lite read in WAIT_SPI_TXN_DONE_S checking + if (ADDRESS_SIZE_G > 0) then + v.wrData(DATA_SIZE_G+ADDRESS_SIZE_G-1 downto DATA_SIZE_G) := axiReadMaster.araddr(2+ADDRESS_SIZE_G-1 downto 2); -- setup memAddr + end if; else - -- No read bit when mode is read-only if (MODE_G /= "RO") then v.wrData(PACKET_SIZE_C-1) := '1'; end if; - + -- Address if (ADDRESS_SIZE_G > 0) then v.wrData(DATA_SIZE_G+ADDRESS_SIZE_G-1 downto DATA_SIZE_G) := axiReadMaster.araddr(2+ADDRESS_SIZE_G-1 downto 2); @@ -149,7 +165,7 @@ begin -- in shared sdio configurations v.wrData(DATA_SIZE_G-1 downto 0) := (others => '1'); end if; - + -- If there are no address bits, readback will reuse the last wrData when shifting v.chipSel := axiReadMaster.araddr(CHIP_BITS_C+ADDRESS_SIZE_G+1 downto 2+ADDRESS_SIZE_G); v.wrEn := '1'; @@ -164,6 +180,10 @@ begin v.state := WAIT_SPI_TXN_DONE_S; end if; + when WAIT_CYCLE_SHADOW_S => + -- wait for memData + v.state := WAIT_SPI_TXN_DONE_S; + when WAIT_SPI_TXN_DONE_S => if (rdEn = '1') then @@ -171,6 +191,10 @@ begin if (MODE_G = "WO" or (MODE_G = "RW" and r.wrData(PACKET_SIZE_C-1) = '0')) then axiSlaveWriteResponse(v.axiWriteSlave); + elsif (SHADOW_EN_G) then + v.axiReadSlave.rdata := (others => '0'); + v.axiReadSlave.rdata(DATA_SIZE_G-1 downto 0) := memData; + axiSlaveReadResponse(v.axiReadSlave); else v.axiReadSlave.rdata := (others => '0'); v.axiReadSlave.rdata(DATA_SIZE_G-1 downto 0) := rdData(DATA_SIZE_G-1 downto 0); @@ -197,6 +221,18 @@ begin end process comb; + shadow_mem : process (axiClk) is + begin + if (SHADOW_EN_G) then + if (rising_edge(axiClk)) then + if (memWe = '1') then + mem(conv_integer(memAddr)) <= r.wrData; + end if; + memData <= mem(conv_integer(memAddr)); + end if; + end if; + end process shadow_mem; + seq : process (axiClk) is begin if (rising_edge(axiClk)) then From e2274dd1643e76d450bd4c4eff13d91c1ea4bb8d Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 27 Mar 2019 13:06:23 -0700 Subject: [PATCH 62/92] Update AxiDualPortRam.vhd --- axi/axi-lite/rtl/AxiDualPortRam.vhd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/axi/axi-lite/rtl/AxiDualPortRam.vhd b/axi/axi-lite/rtl/AxiDualPortRam.vhd index 3010bdc4ac..ce267f8978 100644 --- a/axi/axi-lite/rtl/AxiDualPortRam.vhd +++ b/axi/axi-lite/rtl/AxiDualPortRam.vhd @@ -136,7 +136,7 @@ begin clkb => clk, enb => en, web => weByteMask, - rstb => rst, + rstb => '0', addrb => addr, dinb => din, doutb => doutInt); @@ -166,7 +166,7 @@ begin clkb => clk, enb => en, web => weByteMask, - rstb => rst, + rstb => '0', addrb => addr, dinb => din, doutb => doutInt); @@ -192,7 +192,7 @@ begin ena => en, wea => we, weaByte => weByte, - rsta => rst, + rsta => '0', addra => addr, dina => din, douta => doutInt, @@ -229,7 +229,7 @@ begin douta => axiDout(DATA_WIDTH_G-1 downto 0), clkb => clk, enb => en, - rstb => rst, + rstb => '0', addrb => addr, doutb => doutInt); end generate; @@ -259,7 +259,7 @@ begin enb => en, -- [in] web => we, -- [in] webByte => weByte, -- [in] - rstb => rst, -- [in] + rstb => '0', -- [in] addrb => addr, -- [in] dinb => din, -- [in] doutb => doutInt); -- [out] From 79bf7a1a5e9dbac18b0930486bb67214da568702 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 27 Mar 2019 14:58:47 -0700 Subject: [PATCH 63/92] adding surf.protocols.clink._ClockManager --- python/surf/protocols/clink/_ClinkChannel.py | 10 +- python/surf/protocols/clink/_ClinkTop.py | 53 +++++- python/surf/protocols/clink/_ClockManager.py | 175 ++++++++++++++++++ .../surf/protocols/clink/_UartUp900cl12b.py | 2 +- python/surf/protocols/clink/__init__.py | 1 + 5 files changed, 229 insertions(+), 12 deletions(-) create mode 100644 python/surf/protocols/clink/_ClockManager.py diff --git a/python/surf/protocols/clink/_ClinkChannel.py b/python/surf/protocols/clink/_ClinkChannel.py index da26ccf734..171eee7610 100644 --- a/python/surf/protocols/clink/_ClinkChannel.py +++ b/python/surf/protocols/clink/_ClinkChannel.py @@ -124,6 +124,7 @@ def __init__( self, disp = '{}', mode = "RW", units = "microsec", + value = 30000, # 30ms/byte )) self.add(pr.RemoteVariable( @@ -199,6 +200,9 @@ def __init__( self, # Check for OPA1000 camera if (camType=='Opal000'): + + # Override defaults + self.BaudRate._default = 57600 # Add the device self.add(cl.UartOpal000( @@ -207,9 +211,6 @@ def __init__( self, expand = False, )) - # Override default baud rate - self.BaudRate._default = 57600 - # Check for Piranha4 camera elif (camType=='Piranha4'): @@ -223,6 +224,9 @@ def __init__( self, # Check for Uniq UP-900CL-12B camera elif (camType=='Up900cl12b'): + # Override defaults + self.SerThrottle._default = 30000 + # Add the device self.add(cl.UartUp900cl12b( name = 'UartUp900cl12b', diff --git a/python/surf/protocols/clink/_ClinkTop.py b/python/surf/protocols/clink/_ClinkTop.py index 9cb4e86f1e..00b93f0203 100644 --- a/python/surf/protocols/clink/_ClinkTop.py +++ b/python/surf/protocols/clink/_ClinkTop.py @@ -19,7 +19,6 @@ import pyrogue as pr import surf.protocols.clink as cl -import surf.xilinx as xil class ClinkTop(pr.Device): def __init__( self, @@ -42,15 +41,21 @@ def __init__( self, bitOffset = 0x00, mode = "RO", )) - - self.add(pr.RemoteCommand( - name = "ResetPll", + + self.add(pr.RemoteVariable( + name = "RstPll", description = "Camera link channel PLL reset", offset = 0x04, bitSize = 1, bitOffset = 0, - function = pr.BaseCommand.toggle, - )) + mode = "RW", + hidden = True, + )) + + @self.command(description="toggles Camera link channel PLL reset",) + def ResetPll(): + self.RstPll.set(0x1) + self.RstPll.set(0x0) self.add(pr.RemoteCommand( name = "ResetFsm", @@ -234,18 +239,50 @@ def __init__( self, # expand = False, )) for i in range(3): - self.add(xil.ClockManager( + self.add(cl.ClockManager( name = f'Pll[{i}]', offset = 0x1000+(i*0x1000), type = 'MMCME2', expand = False, )) + for i in range(3): + self.add(pr.LocalVariable( + name = f'PllConfig[{i}]', + description = 'Sets the PLL to a known set of configurations', + mode = 'RW', + value = '', + )) + def hardReset(self): + self.ResetPll() self.CntRst() def softReset(self): + # Hold the PLL in reset before configuration + self.RstPll.set(0x1) + + # Loop through the PLL modules + for i in range(3): + + # Check for 85 MHz configuration + if (self.PllConfig[i].get() == '85MHz'): + self.Pll[i].Config85MHz() + + # Check for 80 MHz configuration + if (self.PllConfig[i].get() == '80MHz'): + # Same config as 85 MHz + self.Pll[i].Config85MHz() + + # Check for 25 MHz configuration + if (self.PllConfig[i].get() == '25MHz'): + self.Pll[i].Config25MHz() + + # Release the reset after configuration + self.RstPll.set(0x0) + + # Reset all the counters self.CntRst() def countReset(self): - self.CntRst() \ No newline at end of file + self.CntRst() diff --git a/python/surf/protocols/clink/_ClockManager.py b/python/surf/protocols/clink/_ClockManager.py new file mode 100644 index 0000000000..e690daa7ad --- /dev/null +++ b/python/surf/protocols/clink/_ClockManager.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr +import surf.xilinx as xil + +class ClockManager(xil.ClockManager): + def __init__(self,**kwargs): + super().__init__(**kwargs) + + @self.command(description="Sets the 85 MHz configuration",) + def Config85MHz(): + self.POWER.set(0xffff) + self.PHASE_MUX[0].set(0x0) + self.HIGH_TIME[0].set(0x7) + self.LOW_TIME[0].set(0x7) + self.PHASE_MUX[1].set(0x0) + self.HIGH_TIME[1].set(0x1) + self.LOW_TIME[1].set(0x1) + self.PHASE_MUX[2].set(0x0) + self.HIGH_TIME[2].set(0x1) + self.LOW_TIME[2].set(0x1) + self.PHASE_MUX[3].set(0x0) + self.HIGH_TIME[3].set(0x1) + self.LOW_TIME[3].set(0x1) + self.PHASE_MUX[4].set(0x0) + self.HIGH_TIME[4].set(0x1) + self.LOW_TIME[4].set(0x1) + self.PHASE_MUX[5].set(0x0) + self.HIGH_TIME[5].set(0x1) + self.LOW_TIME[5].set(0x1) + self.PHASE_MUX[6].set(0x0) + self.HIGH_TIME[6].set(0x1) + self.LOW_TIME[6].set(0x1) + self.PHASE_MUX_FB.set(0x0) + self.HIGH_TIME_FB.set(0x7) + self.LOW_TIME_FB.set(0x7) + self.FRAC[0].set(0x0) + self.FRAC_EN[0].set(0x0) + self.FRAC_WF_R[0].set(0x0) + self.MX[0].set(0x0) + self.EDGE[0].set(0x0) + self.NO_COUNT[0].set(0x0) + self.DELAY_TIME[0].set(0x0) + self.MX[1].set(0x0) + self.EDGE[1].set(0x0) + self.NO_COUNT[1].set(0x0) + self.DELAY_TIME[1].set(0x0) + self.MX[2].set(0x0) + self.EDGE[2].set(0x0) + self.NO_COUNT[2].set(0x1) + self.DELAY_TIME[2].set(0x0) + self.MX[3].set(0x0) + self.EDGE[3].set(0x0) + self.NO_COUNT[3].set(0x1) + self.DELAY_TIME[3].set(0x0) + self.MX[4].set(0x0) + self.EDGE[4].set(0x0) + self.NO_COUNT[4].set(0x1) + self.DELAY_TIME[4].set(0x0) + self.PHASE_MUX_F_CLKOUT[0].set(0x0) + self.FRAC_WF_F_CLKOUT[0].set(0x0) + self.MX[5].set(0x0) + self.EDGE[5].set(0x0) + self.NO_COUNT[5].set(0x1) + self.DELAY_TIME[5].set(0x0) + self.PHASE_MUX_F_CLKOUT_FB.set(0x0) + self.FRAC_WF_F_CLKOUT_FB.set(0x0) + self.MX[6].set(0x0) + self.EDGE[6].set(0x0) + self.NO_COUNT[6].set(0x1) + self.DELAY_TIME[6].set(0x0) + self.FRAC_FB.set(0x0) + self.FRAC_EN_FB.set(0x0) + self.FRAC_WF_R_FB.set(0x0) + self.MX_FB.set(0x0) + self.EDGE_FB.set(0x0) + self.NO_COUNT_FB.set(0x0) + self.DELAY_TIME_FB.set(0x0) + self.EDGE_DIV.set(0x0) + self.NO_COUNT_DIV.set(0x1) + self.HIGH_TIME_DIV.set(0x1) + self.LOW_TIME_DIV.set(0x1) + self.LockReg[0].set(0x2bc) + self.LockReg[1].set(0x7c01) + self.LockReg[2].set(0xffe9) + self.FiltReg[0].set(0x9908) + self.FiltReg[1].set(0x8100) + + @self.command(description="Sets the 25 MHz configuration",) + def Config25MHz(): + self.POWER.set(0xffff) + self.PHASE_MUX[0].set(0x0) + self.HIGH_TIME[0].set(0x15) + self.LOW_TIME[0].set(0x15) + self.PHASE_MUX[1].set(0x0) + self.HIGH_TIME[1].set(0x3) + self.LOW_TIME[1].set(0x3) + self.PHASE_MUX[2].set(0x0) + self.HIGH_TIME[2].set(0x1) + self.LOW_TIME[2].set(0x1) + self.PHASE_MUX[3].set(0x0) + self.HIGH_TIME[3].set(0x1) + self.LOW_TIME[3].set(0x1) + self.PHASE_MUX[4].set(0x0) + self.HIGH_TIME[4].set(0x1) + self.LOW_TIME[4].set(0x1) + self.PHASE_MUX[5].set(0x0) + self.HIGH_TIME[5].set(0x1) + self.LOW_TIME[5].set(0x1) + self.PHASE_MUX[6].set(0x0) + self.HIGH_TIME[6].set(0x1) + self.LOW_TIME[6].set(0x1) + self.PHASE_MUX_FB.set(0x0) + self.HIGH_TIME_FB.set(0x15) + self.LOW_TIME_FB.set(0x15) + self.FRAC[0].set(0x0) + self.FRAC_EN[0].set(0x0) + self.FRAC_WF_R[0].set(0x0) + self.MX[0].set(0x0) + self.EDGE[0].set(0x0) + self.NO_COUNT[0].set(0x0) + self.DELAY_TIME[0].set(0x0) + self.MX[1].set(0x0) + self.EDGE[1].set(0x0) + self.NO_COUNT[1].set(0x0) + self.DELAY_TIME[1].set(0x0) + self.MX[2].set(0x0) + self.EDGE[2].set(0x0) + self.NO_COUNT[2].set(0x1) + self.DELAY_TIME[2].set(0x0) + self.MX[3].set(0x0) + self.EDGE[3].set(0x0) + self.NO_COUNT[3].set(0x1) + self.DELAY_TIME[3].set(0x0) + self.MX[4].set(0x0) + self.EDGE[4].set(0x0) + self.NO_COUNT[4].set(0x1) + self.DELAY_TIME[4].set(0x0) + self.PHASE_MUX_F_CLKOUT[0].set(0x0) + self.FRAC_WF_F_CLKOUT[0].set(0x0) + self.MX[5].set(0x0) + self.EDGE[5].set(0x0) + self.NO_COUNT[5].set(0x1) + self.DELAY_TIME[5].set(0x0) + self.PHASE_MUX_F_CLKOUT_FB.set(0x0) + self.FRAC_WF_F_CLKOUT_FB.set(0x0) + self.MX[6].set(0x0) + self.EDGE[6].set(0x0) + self.NO_COUNT[6].set(0x1) + self.DELAY_TIME[6].set(0x0) + self.FRAC_FB.set(0x0) + self.FRAC_EN_FB.set(0x0) + self.FRAC_WF_R_FB.set(0x0) + self.MX_FB.set(0x0) + self.EDGE_FB.set(0x0) + self.NO_COUNT_FB.set(0x0) + self.DELAY_TIME_FB.set(0x0) + self.EDGE_DIV.set(0x0) + self.NO_COUNT_DIV.set(0x1) + self.HIGH_TIME_DIV.set(0x1) + self.LOW_TIME_DIV.set(0x1) + self.LockReg[0].set(0xfa) + self.LockReg[1].set(0x7c01) + self.LockReg[2].set(0xffe9) + self.FiltReg[0].set(0x808) + self.FiltReg[1].set(0x8000) diff --git a/python/surf/protocols/clink/_UartUp900cl12b.py b/python/surf/protocols/clink/_UartUp900cl12b.py index 8c60f0dc88..c203c5f215 100644 --- a/python/surf/protocols/clink/_UartUp900cl12b.py +++ b/python/surf/protocols/clink/_UartUp900cl12b.py @@ -121,7 +121,7 @@ def sendString(arg): self.add(pr.BaseCommand( name = 'AM', description = 'Asynchronous mode: Asynchronous reset', - function = lambda cmd: self._tx.sendString('nm') + function = lambda cmd: self._tx.sendString('am') )) self.add(pr.LocalVariable( diff --git a/python/surf/protocols/clink/__init__.py b/python/surf/protocols/clink/__init__.py index 86a45453f2..75717fa8a4 100644 --- a/python/surf/protocols/clink/__init__.py +++ b/python/surf/protocols/clink/__init__.py @@ -13,6 +13,7 @@ from surf.protocols.clink._ClinkSerialRx import * from surf.protocols.clink._ClinkSerialTx import * from surf.protocols.clink._ClinkChannel import * +from surf.protocols.clink._ClockManager import * # Library of support Camera UART interfaces from surf.protocols.clink._UartGeneric import * From 5b5e19f1fa2bc30c0049f964b9e083d950f373f6 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 28 Mar 2019 16:29:41 -0700 Subject: [PATCH 64/92] Fix typo --- python/surf/protocols/pgp/_Pgp2bAxi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/surf/protocols/pgp/_Pgp2bAxi.py b/python/surf/protocols/pgp/_Pgp2bAxi.py index b56218d76b..b72f5c5670 100644 --- a/python/surf/protocols/pgp/_Pgp2bAxi.py +++ b/python/surf/protocols/pgp/_Pgp2bAxi.py @@ -206,7 +206,7 @@ def __init__(self, "RxRemOverflow1Count", "RxRemOverflow2Count", "RxRemOverflow3Count", - "RxFrameErrorCoumt", + "RxFrameErrorCount", "RxFrameCount", "TxLocOverflow0Count", "TxLocOverflow1Count", From 2694c362fe86bc83547390b37311a66b1d91011a Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 1 Apr 2019 15:19:47 -0700 Subject: [PATCH 65/92] adding Sgmii88E1111LvdsUltraScale module --- .../Sgmii88E1111/core/Sgmii88E1111Mdio.vhd | 177 +++++++++++++++ .../Sgmii88E1111LvdsUltraScale.vhd | 207 ++++++++++++++++++ devices/Marvell/Sgmii88E1111/ruckus.tcl | 15 ++ devices/Marvell/ruckus.tcl | 5 + devices/ruckus.tcl | 1 + ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl | 3 +- 6 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 devices/Marvell/Sgmii88E1111/core/Sgmii88E1111Mdio.vhd create mode 100644 devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd create mode 100644 devices/Marvell/Sgmii88E1111/ruckus.tcl create mode 100644 devices/Marvell/ruckus.tcl diff --git a/devices/Marvell/Sgmii88E1111/core/Sgmii88E1111Mdio.vhd b/devices/Marvell/Sgmii88E1111/core/Sgmii88E1111Mdio.vhd new file mode 100644 index 0000000000..b9f46790b6 --- /dev/null +++ b/devices/Marvell/Sgmii88E1111/core/Sgmii88E1111Mdio.vhd @@ -0,0 +1,177 @@ +------------------------------------------------------------------------------- +-- File : Sgmii88E1111Mdio.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Controller for the Marvell 88E1111 PHY +------------------------------------------------------------------------------- +-- 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.numeric_std.all; + +use work.StdRtlPkg.all; +use work.MdioPkg.all; + +entity Sgmii88E1111Mdio is + generic ( + TPD_G : time := 1 ns; + -- half-period of MDC in clk cycles + DIV_G : natural range 1 to natural'high := 1; + PHY_G : natural range 0 to 31 := 7); + port ( + -- clock and reset + clk : in sl; + rst : in sl; + -- misc + initDone : out sl; + speed_is_10_100 : out sl; + speed_is_100 : out sl; + linkIsUp : out sl; + -- MDIO interface + mdc : out sl; + mdo : out sl; + mdi : in sl; + -- link status change interrupt + linkIrq : in sl); +end entity Sgmii88E1111Mdio; + +architecture rtl of Sgmii88E1111Mdio is + + -- the initialization sequence: + -- 1) sets up advertisement for supported ANEG modes on the copper-side of the PHY + -- (all speeds, FD only - the SURF Ethernet mac doesn't support HD, AFAIK). + -- 2) disables auto-negotiation on the SGMII side (since there is no support in the + -- FW. + -- 3) enables link status change interrupts. + -- + -- This module monitors link-status changes and obtains updated link status and + -- speed from the PHY so that the user may switch the MAC to the correct speed. + + constant P_INIT_C : MdioProgramArray := + ( + mdioWriteInst(PHY_G, 22, X"0001", false), -- select page 1 + mdioWriteInst(PHY_G, 0, X"0140", false), -- disable ANEG on SMII side + mdioWriteInst(PHY_G, 22, X"0000", false), -- select page 0 + mdioWriteInst(PHY_G, 4, X"0140", false), -- advertise 10/100 FD only + mdioWriteInst(PHY_G, 9, X"0200", false), -- advertise 1000 FD only + mdioWriteInst(PHY_G, 18, X"0c00", false), -- enable link status and ANEG IRQ + mdioWriteInst(PHY_G, 0, X"1340", true) -- restart copper ANEG + ); + + constant REG19_IDX_C : natural := 0; + constant REG17_IDX_C : natural := 1; + + -- IRQ Handler sequence: + -- 1) read back and clear interrupts (reading does clear them) + -- 2) obtain current link status and speed + constant P_HDLR_C : MdioProgramArray := + ( + REG19_IDX_C => mdioReadInst(PHY_G, 19, false), -- read/ack/clear interrupt + REG17_IDX_C => mdioReadInst(PHY_G, 17, true) -- read current speed and link status + ); + + constant NUM_READ_ARGS_C : natural := mdioProgNumReadTransactions(P_HDLR_C); + + type RegType is record + s10_100 : sl; + s100 : sl; + linkIsUp : sl; + end record RegType; + + constant REG_INIT_C : RegType := ( + s10_100 => '0', + s100 => '0', + linkIsUp => '0' + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal hdlrDone : sl; + signal args : Slv16Array(0 to NUM_READ_ARGS_C - 1); + +begin + + speed_is_10_100 <= r.s10_100; + speed_is_100 <= r.s100; + linkIsUp <= r.linkIsUp; + + U_MdioLinkIrqHandler : entity work.MdioLinkIrqHandler + generic map ( + TPD_G => TPD_G, + DIV_G => DIV_G, + PROG_INIT_G => P_INIT_C, + PROG_HDLR_G => P_HDLR_C, + NUM_HDLR_ARGS_G => NUM_READ_ARGS_C + ) + port map ( + clk => clk, + rst => rst, + + initDone => initDone, + hdlrDone => hdlrDone, + args => args, + + mdc => mdc, + mdi => mdi, + mdo => mdo, + + phyIrq => linkIrq + ); + + COMB : process(args, hdlrDone, r) + variable v : RegType; + variable r17 : slv(15 downto 0); + begin + + v := r; + + if (hdlrDone /= '0') then + + r17 := args(REG17_IDX_C); + + v.linkIsUp := r17(11); + + if (v.linkIsUp /= '0') then + -- link is good + case r17(15 downto 14) is + when "10" => -- 1000Mbps + v.s10_100 := '0'; + v.s100 := '0'; + when "01" => -- 100Mbps + v.s10_100 := '1'; + v.s100 := '1'; + when "00" => -- 10Mbps + v.s10_100 := '1'; + v.s100 := '0'; + when others => -- reserved; should not happen + end case; + end if; + + end if; + + rin <= v; + + end process COMB; + + SEQ : process(clk) + begin + if (rising_edge(clk)) then + if (rst /= '0') then + r <= REG_INIT_C; + else + r <= rin after TPD_G; + end if; + end if; + end process SEQ; + +end rtl; + diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd new file mode 100644 index 0000000000..84d5cb9675 --- /dev/null +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -0,0 +1,207 @@ +------------------------------------------------------------------------------- +-- File : Sgmii88E1111LvdsUltraScale.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Controller for the Marvell 88E1111 PHY +------------------------------------------------------------------------------- +-- 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.numeric_std.all; + +use work.StdRtlPkg.all; +use work.AxiStreamPkg.all; +use work.AxiLitePkg.all; +use work.EthMacPkg.all; + +entity Sgmii88E1111LvdsUltraScale is + generic ( + TPD_G : time := 1 ns; + STABLE_CLK_FREQ_G : real := 156.25E+6; + PHY_G : natural range 0 to 31 := 7; + AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); + port ( + -- clock and reset + extRst : in sl; + stableClk : in sl; + -- Local Configurations + localMac : in slv(47 downto 0); -- big-Endian configuration + -- Interface to Ethernet Media Access Controller (MAC) + macClk : in sl; -- Stable clock reference + macRst : in sl; + obMacMaster : out AxiStreamMasterType; + obMacSlave : in AxiStreamSlaveType; + ibMacMaster : in AxiStreamMasterType; + ibMacSlave : out AxiStreamSlaveType; + -- ETH external PHY Ports + phyClkP : in sl; -- 625.0 MHz + phyClkN : in sl; + phyMdc : out sl; + phyMdio : inout sl; + phyRstN : out sl; -- active low + phyIrqN : in sl; -- active low + -- LVDS SGMII Ports + sgmiiRxP : in sl; + sgmiiRxN : in sl; + sgmiiTxP : out sl; + sgmiiTxN : out sl); +end entity Sgmii88E1111LvdsUltraScale; + +architecture mapping of Sgmii88E1111LvdsUltraScale is + + signal phyClk : sl; + signal phyRst : sl; + signal phyReady : sl; + + signal phyInitRst : sl; + signal phyIrq : sl; + signal phyMdi : sl; + signal phyMdo : sl := '1'; + + signal extPhyRstN : sl := '0'; + signal extPhyReady : sl := '0'; + + signal speed10_100 : sl := '0'; + signal speed100 : sl := '0'; + signal linkIsUp : sl := '0'; + signal initDone : sl := '0'; + +begin + + -- Tri-state driver for phyMdio + phyMdio <= 'Z' when phyMdo = '1' else '0'; + + -- Reset line of the external phy + phyRstN <= extPhyRstN; + + -------------------------------------------------------------------------- + -- We must hold reset for >10ms and then wait >5ms until we may talk + -- to it (we actually wait also >10ms) which is indicated by 'extPhyReady' + -------------------------------------------------------------------------- + U_PwrUpRst0 : entity work.PwrUpRst + generic map( + TPD_G => TPD_G, + IN_POLARITY_G => '1', + OUT_POLARITY_G => '0', + DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 100.0)) -- 10 ms reset + port map ( + arst => extRst, + clk => stableClk, + rstOut => extPhyRstN); + + U_PwrUpRst1 : entity work.PwrUpRst + generic map( + TPD_G => TPD_G, + IN_POLARITY_G => '0', + OUT_POLARITY_G => '0', + DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 100.0)) -- 10 ms reset + port map ( + arst => extPhyRstN, + clk => stableClk, + rstOut => extPhyReady); + + ---------------------------------------------------------------------- + -- The MDIO controller which talks to the external PHY must be held + -- in reset until extPhyReady; it works in a different clock domain... + ---------------------------------------------------------------------- + U_PhyInitRstSync : entity work.RstSync + generic map ( + IN_POLARITY_G => '0', + OUT_POLARITY_G => '1') + port map ( + clk => phyClk, + asyncRst => extPhyReady, + syncRst => phyInitRst); + + ----------------------------------------------------------------------- + -- The SaltCore does not support auto-negotiation on the SGMII link + -- (mac<->phy) - however, the Marvell PHY (by default) assumes it does. + -- We need to disable auto-negotiation in the PHY on the SGMII side + -- and handle link changes (aneg still enabled on copper) flagged + -- by the PHY... + ----------------------------------------------------------------------- + U_PhyCtrl : entity work.Sgmii88E1111Mdio + generic map ( + TPD_G => TPD_G, + PHY_G => PHY_G, + DIV_G => 100) + port map ( + clk => phyClk, + rst => phyInitRst, + initDone => initDone, + speed_is_10_100 => speed10_100, + speed_is_100 => speed100, + linkIsUp => linkIsUp, + mdi => phyMdi, + mdc => phyMdc, + mdo => phyMdo, + linkIrq => phyIrq); + + ---------------------------------------------------- + -- synchronize MDI and IRQ signals into 'clk' domain + ---------------------------------------------------- + U_SyncMdi : entity work.Synchronizer + generic map ( + TPD_G => TPD_G) + port map ( + clk => phyClk, + dataIn => phyMdio, + dataOut => phyMdi); + + U_SyncIrq : entity work.Synchronizer + generic map ( + TPD_G => TPD_G, + OUT_POLARITY_G => '0', + INIT_G => "11") + port map ( + clk => phyClk, + dataIn => phyIrqN, + dataOut => phyIrq); + + U_1GigE : entity work.GigEthLvdsUltraScaleWrapper + generic map ( + TPD_G => TPD_G, + -- DMA/MAC Configurations + NUM_LANE_G => 1, + -- MMCM Configuration + USE_REFCLK_G => false, + CLKIN_PERIOD_G => 1.6, -- 625.0 MHz + DIVCLK_DIVIDE_G => 2, -- 312.5 MHz + CLKFBOUT_MULT_F_G => 2.0, -- VCO: 625 MHz + -- AXI Streaming Configurations + AXIS_CONFIG_G =>(others => AXIS_CONFIG_G)) + port map ( + -- Local Configurations + localMac(0) => localMac, + -- Streaming DMA Interface + dmaClk(0) => macClk, + dmaRst(0) => macRst, + dmaIbMasters(0) => obMacMaster, + dmaIbSlaves(0) => obMacSlave, + dmaObMasters(0) => ibMacMaster, + dmaObSlaves(0) => ibMacSlave, + -- Misc. Signals + extRst => extRst, + phyClk => phyClk, + phyRst => phyRst, + phyReady(0) => phyReady, + speed_is_10_100(0) => speed10_100, + speed_is_100(0) => speed100, + -- MGT Clock Port + sgmiiClkP => phyClkP, + sgmiiClkN => phyClkN, + -- MGT Ports + sgmiiTxP(0) => sgmiiTxP, + sgmiiTxN(0) => sgmiiTxN, + sgmiiRxP(0) => sgmiiRxP, + sgmiiRxN(0) => sgmiiRxN); + +end mapping; diff --git a/devices/Marvell/Sgmii88E1111/ruckus.tcl b/devices/Marvell/Sgmii88E1111/ruckus.tcl new file mode 100644 index 0000000000..294dfd62b8 --- /dev/null +++ b/devices/Marvell/Sgmii88E1111/ruckus.tcl @@ -0,0 +1,15 @@ +# Load RUCKUS environment and library +source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl + +# Load the source code +loadSource -dir "$::DIR_PATH/core" + +# Get the family type +set family [getFpgaFamily] + +if { ${family} eq {kintexu} || + ${family} eq {kintexuplus} || + ${family} eq {virtexuplus} || + ${family} eq {zynquplus} } { + loadSource -dir "$::DIR_PATH/lvdsUltraScale" +} diff --git a/devices/Marvell/ruckus.tcl b/devices/Marvell/ruckus.tcl new file mode 100644 index 0000000000..a968bc11d5 --- /dev/null +++ b/devices/Marvell/ruckus.tcl @@ -0,0 +1,5 @@ +# Load RUCKUS environment and library +source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl + +# Load ruckus files +loadRuckusTcl "$::DIR_PATH/Sgmii88E1111" diff --git a/devices/ruckus.tcl b/devices/ruckus.tcl index cad45d19f4..d6bd9f72e8 100644 --- a/devices/ruckus.tcl +++ b/devices/ruckus.tcl @@ -4,6 +4,7 @@ source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl # Load ruckus files loadRuckusTcl "$::DIR_PATH/AnalogDevices" loadRuckusTcl "$::DIR_PATH/Linear" +loadRuckusTcl "$::DIR_PATH/Marvell" loadRuckusTcl "$::DIR_PATH/Microchip" loadRuckusTcl "$::DIR_PATH/Micron" loadRuckusTcl "$::DIR_PATH/Silabs" diff --git a/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl b/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl index 7cc0bd0a2c..7eedd42379 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl +++ b/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl @@ -1,11 +1,12 @@ # Load RUCKUS environment and library source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl +loadSource -dir "$::DIR_PATH/rtl" + if { [info exists ::env(INCLUDE_ETH_SGMII_LVDS)] != 1 || $::env(INCLUDE_ETH_SGMII_LVDS) == 0 } { set useEthSgmiiLvds 0 } else { - loadSource -dir "$::DIR_PATH/rtl" loadConstraints -path "$::DIR_PATH/xdc/GigEthLvdsClockMux.xdc" set_property SCOPED_TO_REF GigEthLvdsClockMux [get_files "$::DIR_PATH/xdc/GigEthLvdsClockMux.xdc"] From b6bdd1b1e86b3f015682435b99e36ce67924fa7a Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 1 Apr 2019 15:22:08 -0700 Subject: [PATCH 66/92] Update Sgmii88E1111LvdsUltraScale.vhd --- .../Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 84d5cb9675..693f097266 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -2,7 +2,7 @@ -- File : Sgmii88E1111LvdsUltraScale.vhd -- Company : SLAC National Accelerator Laboratory ------------------------------------------------------------------------------- --- Description: Controller for the Marvell 88E1111 PHY +-- Description: Wrapper for Marvell 88E1111 PHY + GigEthLvdsUltraScaleWrapper ------------------------------------------------------------------------------- -- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the From 9461d2f2f2d655c347a4f4787b8762a4dc12d995 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 1 Apr 2019 15:22:26 -0700 Subject: [PATCH 67/92] Update Sgmii88E1111LvdsUltraScale.vhd --- .../lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 693f097266..8436a813c9 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -30,12 +30,12 @@ entity Sgmii88E1111LvdsUltraScale is AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- clock and reset - extRst : in sl; + extRst : in sl; -- Stable clock reference stableClk : in sl; -- Local Configurations localMac : in slv(47 downto 0); -- big-Endian configuration -- Interface to Ethernet Media Access Controller (MAC) - macClk : in sl; -- Stable clock reference + macClk : in sl; macRst : in sl; obMacMaster : out AxiStreamMasterType; obMacSlave : in AxiStreamSlaveType; From 7039bb91b00cab3a6d7ec366a8a033695ac4b3ae Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 1 Apr 2019 15:22:50 -0700 Subject: [PATCH 68/92] Update Sgmii88E1111LvdsUltraScale.vhd --- .../lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 8436a813c9..cc2283a333 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -30,8 +30,8 @@ entity Sgmii88E1111LvdsUltraScale is AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- clock and reset - extRst : in sl; -- Stable clock reference - stableClk : in sl; + extRst : in sl; -- active high + stableClk : in sl; -- Stable clock reference -- Local Configurations localMac : in slv(47 downto 0); -- big-Endian configuration -- Interface to Ethernet Media Access Controller (MAC) From 39b293ea1c17e38fc24a046566b7294eb8c2d87c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 2 Apr 2019 14:15:08 -0700 Subject: [PATCH 69/92] adding status signals to top --- .../Sgmii88E1111LvdsUltraScale.vhd | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index cc2283a333..47815af0d2 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -30,12 +30,19 @@ entity Sgmii88E1111LvdsUltraScale is AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- clock and reset - extRst : in sl; -- active high - stableClk : in sl; -- Stable clock reference - -- Local Configurations + extRst : in sl; -- active high + stableClk : in sl; -- Stable clock reference + phyClk : out sl; + phyRst : out sl; + -- Local Configurations/status localMac : in slv(47 downto 0); -- big-Endian configuration + phyReady : out sl; + linkUp : out sl; + speed10 : out sl; + speed100 : out sl; + speed1000 : out sl; -- Interface to Ethernet Media Access Controller (MAC) - macClk : in sl; + macClk : in sl; macRst : in sl; obMacMaster : out AxiStreamMasterType; obMacSlave : in AxiStreamSlaveType; @@ -57,9 +64,8 @@ end entity Sgmii88E1111LvdsUltraScale; architecture mapping of Sgmii88E1111LvdsUltraScale is - signal phyClk : sl; - signal phyRst : sl; - signal phyReady : sl; + signal phyClock : sl; + signal phyReset : sl; signal phyInitRst : sl; signal phyIrq : sl; @@ -69,13 +75,19 @@ architecture mapping of Sgmii88E1111LvdsUltraScale is signal extPhyRstN : sl := '0'; signal extPhyReady : sl := '0'; - signal speed10_100 : sl := '0'; - signal speed100 : sl := '0'; - signal linkIsUp : sl := '0'; - signal initDone : sl := '0'; + signal sp10_100 : sl := '0'; + signal sp100 : sl := '0'; + signal initDone : sl := '0'; begin + phyClk <= phyClock; + phyRst <= phyReset; + + speed10 <= sp10_100 and not sp100; + speed100 <= sp10_100 and not sp100; + speed1000 <= not sp10_100 and not sp100; + -- Tri-state driver for phyMdio phyMdio <= 'Z' when phyMdo = '1' else '0'; @@ -117,7 +129,7 @@ begin IN_POLARITY_G => '0', OUT_POLARITY_G => '1') port map ( - clk => phyClk, + clk => phyClock, asyncRst => extPhyReady, syncRst => phyInitRst); @@ -134,12 +146,12 @@ begin PHY_G => PHY_G, DIV_G => 100) port map ( - clk => phyClk, + clk => phyClock, rst => phyInitRst, initDone => initDone, - speed_is_10_100 => speed10_100, - speed_is_100 => speed100, - linkIsUp => linkIsUp, + speed_is_10_100 => sp10_100, + speed_is_100 => sp100, + linkIsUp => linkUp, mdi => phyMdi, mdc => phyMdc, mdo => phyMdo, @@ -152,7 +164,7 @@ begin generic map ( TPD_G => TPD_G) port map ( - clk => phyClk, + clk => phyClock, dataIn => phyMdio, dataOut => phyMdi); @@ -162,7 +174,7 @@ begin OUT_POLARITY_G => '0', INIT_G => "11") port map ( - clk => phyClk, + clk => phyClock, dataIn => phyIrqN, dataOut => phyIrq); @@ -177,7 +189,7 @@ begin DIVCLK_DIVIDE_G => 2, -- 312.5 MHz CLKFBOUT_MULT_F_G => 2.0, -- VCO: 625 MHz -- AXI Streaming Configurations - AXIS_CONFIG_G =>(others => AXIS_CONFIG_G)) + AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) port map ( -- Local Configurations localMac(0) => localMac, @@ -190,11 +202,11 @@ begin dmaObSlaves(0) => ibMacSlave, -- Misc. Signals extRst => extRst, - phyClk => phyClk, - phyRst => phyRst, + phyClk => phyClock, + phyRst => phyReset, phyReady(0) => phyReady, - speed_is_10_100(0) => speed10_100, - speed_is_100(0) => speed100, + speed_is_10_100(0) => sp10_100, + speed_is_100(0) => sp100, -- MGT Clock Port sgmiiClkP => phyClkP, sgmiiClkN => phyClkN, From 8c0da1fbf8d3c27973c8b9eb7f628a391d15a7b7 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 2 Apr 2019 17:15:01 -0700 Subject: [PATCH 70/92] Updating ruckus submodule lock due to RogueTcpRogueTcp dependence --- ruckus.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruckus.tcl b/ruckus.tcl index 8cacb6fc12..0107600e1e 100644 --- a/ruckus.tcl +++ b/ruckus.tcl @@ -3,7 +3,7 @@ source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl # Check for submodule tagging if { [info exists ::env(OVERRIDE_SUBMODULE_LOCKS)] != 1 || $::env(OVERRIDE_SUBMODULE_LOCKS) == 0 } { - if { [SubmoduleCheck {ruckus} {1.6.8} ] < 0 } {exit -1} + if { [SubmoduleCheck {ruckus} {1.7.6} ] < 0 } {exit -1} } else { puts "\n\n*********************************************************" puts "OVERRIDE_SUBMODULE_LOCKS != 0" From 2db104f620bb8775741b499a0a8707c8b8079859 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 3 Apr 2019 12:57:15 -0700 Subject: [PATCH 71/92] Update Sgmii88E1111LvdsUltraScale.vhd --- .../Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 47815af0d2..74cef00d30 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -27,7 +27,7 @@ entity Sgmii88E1111LvdsUltraScale is TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; PHY_G : natural range 0 to 31 := 7; - AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); + AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( -- clock and reset extRst : in sl; -- active high From 359efbb9f5f67133e574573af3c1239cca6cf865 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 11:33:38 -0700 Subject: [PATCH 72/92] adding ULTRASCALE support to clink --- .../clink/{hdl => 7Series}/ClinkDataClk.vhd | 0 .../clink/{hdl => 7Series}/ClinkDataShift.vhd | 4 +- protocols/clink/UltraScale/ClinkDataClk.vhd | 199 +++++++++++ protocols/clink/UltraScale/ClinkDataShift.vhd | 311 ++++++++++++++++++ protocols/clink/{hdl => rtl}/ClinkCtrl.vhd | 0 protocols/clink/{hdl => rtl}/ClinkData.vhd | 7 +- protocols/clink/{hdl => rtl}/ClinkFraming.vhd | 0 protocols/clink/{hdl => rtl}/ClinkPkg.vhd | 0 protocols/clink/{hdl => rtl}/ClinkReg.vhd | 0 protocols/clink/{hdl => rtl}/ClinkTop.vhd | 7 +- protocols/clink/{hdl => rtl}/ClinkUart.vhd | 0 .../clink/{hdl => rtl}/ClinkUartThrottle.vhd | 0 protocols/clink/ruckus.tcl | 20 +- protocols/clink/{sim => tb}/ClinkFramerTb.vhd | 0 14 files changed, 536 insertions(+), 12 deletions(-) rename protocols/clink/{hdl => 7Series}/ClinkDataClk.vhd (100%) rename protocols/clink/{hdl => 7Series}/ClinkDataShift.vhd (99%) create mode 100644 protocols/clink/UltraScale/ClinkDataClk.vhd create mode 100644 protocols/clink/UltraScale/ClinkDataShift.vhd rename protocols/clink/{hdl => rtl}/ClinkCtrl.vhd (100%) rename protocols/clink/{hdl => rtl}/ClinkData.vhd (98%) rename protocols/clink/{hdl => rtl}/ClinkFraming.vhd (100%) rename protocols/clink/{hdl => rtl}/ClinkPkg.vhd (100%) rename protocols/clink/{hdl => rtl}/ClinkReg.vhd (100%) rename protocols/clink/{hdl => rtl}/ClinkTop.vhd (98%) rename protocols/clink/{hdl => rtl}/ClinkUart.vhd (100%) rename protocols/clink/{hdl => rtl}/ClinkUartThrottle.vhd (100%) rename protocols/clink/{sim => tb}/ClinkFramerTb.vhd (100%) diff --git a/protocols/clink/hdl/ClinkDataClk.vhd b/protocols/clink/7Series/ClinkDataClk.vhd similarity index 100% rename from protocols/clink/hdl/ClinkDataClk.vhd rename to protocols/clink/7Series/ClinkDataClk.vhd diff --git a/protocols/clink/hdl/ClinkDataShift.vhd b/protocols/clink/7Series/ClinkDataShift.vhd similarity index 99% rename from protocols/clink/hdl/ClinkDataShift.vhd rename to protocols/clink/7Series/ClinkDataShift.vhd index 366fb3c353..b44d48105c 100644 --- a/protocols/clink/hdl/ClinkDataShift.vhd +++ b/protocols/clink/7Series/ClinkDataShift.vhd @@ -28,8 +28,8 @@ use unisim.vcomponents.all; entity ClinkDataShift is generic ( - TPD_G : time := 1 ns - ); + TPD_G : time := 1 ns; + XIL_DEVICE_G : string := "7SERIES"); port ( -- Input clock and data cblHalfP : inout slv(4 downto 0); diff --git a/protocols/clink/UltraScale/ClinkDataClk.vhd b/protocols/clink/UltraScale/ClinkDataClk.vhd new file mode 100644 index 0000000000..c379aefeee --- /dev/null +++ b/protocols/clink/UltraScale/ClinkDataClk.vhd @@ -0,0 +1,199 @@ +------------------------------------------------------------------------------- +-- File : ClinkDataClk.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: A wrapper over MMCM +------------------------------------------------------------------------------- +-- 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 ieee.math_real.all; + +library unisim; +use unisim.vcomponents.all; + +use work.StdRtlPkg.all; +use work.AxiLitePkg.all; + +entity ClinkDataClk is + generic ( + TPD_G : time := 1 ns; + REG_BUFF_EN_G : boolean := false); + port ( + clkIn : in sl; + rstIn : in sl; + clinkClk7x : out sl; + clinkClk : out sl; + clinkRst : out sl; + -- AXI-Lite Interface + sysClk : in sl; + sysRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end entity ClinkDataClk; + +architecture rtl of ClinkDataClk is + + signal clkInLoc : sl; + signal clkOutMmcm : slv(1 downto 0); + signal clkOutLoc : slv(1 downto 0); + signal clkFbOut : sl; + signal clkFbIn : sl; + signal lockedLoc : sl; + signal genReset : sl; + + signal drpRdy : sl; + signal drpEn : sl; + signal drpWe : sl; + signal drpAddr : slv(6 downto 0); + signal drpDi : slv(15 downto 0); + signal drpDo : slv(15 downto 0); + +begin + + U_AxiLiteToDrp : entity work.AxiLiteToDrp + generic map ( + TPD_G => TPD_G, + COMMON_CLK_G => true, + EN_ARBITRATION_G => false, + TIMEOUT_G => 4096, + ADDR_WIDTH_G => 7, + DATA_WIDTH_G => 16) + port map ( + -- AXI-Lite Port + axilClk => sysClk, + axilRst => sysRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave, + -- DRP Interface + drpClk => sysClk, + drpRst => sysRst, + drpRdy => drpRdy, + drpEn => drpEn, + drpWe => drpWe, + drpAddr => drpAddr, + drpDi => drpDi, + drpDo => drpDo); + + U_Mmcm : MMCME2_ADV + generic map ( + BANDWIDTH => "OPTIMIZED", + CLKOUT4_CASCADE => false, + STARTUP_WAIT => false, +-- CLKIN1_PERIOD => 40.0, -- 25 MHz +-- DIVCLK_DIVIDE => 1, +-- CLKFBOUT_MULT_F => 42.0, -- VCO = 1050MHz +-- CLKOUT0_DIVIDE_F => 42.0, -- 25 MHz +-- CLKOUT1_DIVIDE => 6) -- 175MHz + CLKIN1_PERIOD => 11.764, -- 85 MHz (CLKIN[min.] = 43 MHz, CLKIN[max] = 102 MHz) + DIVCLK_DIVIDE => 1, + CLKFBOUT_MULT_F => 14.0, -- VCO = 1190MHz (VCO[min] = 600 MHz, VCO[max] = 1440 MHz) + CLKOUT0_DIVIDE_F => 14.0, -- 85 MHz = 1190MHz/14 + CLKOUT1_DIVIDE => 2) -- 595MHz = 1190MHz/2 + port map ( + DCLK => sysClk, + DRDY => drpRdy, + DEN => drpEn, + DWE => drpWe, + DADDR => drpAddr, + DI => drpDi, + DO => drpDo, + PSCLK => '0', + PSEN => '0', + PSINCDEC => '0', + PWRDWN => '0', + RST => rstIn, + CLKIN1 => clkInLoc, + CLKIN2 => '0', + CLKINSEL => '1', + CLKFBOUT => clkFbOut, + CLKFBIN => clkFbIn, + LOCKED => lockedLoc, + CLKOUT0 => clkOutMmcm(0), + CLKOUT1 => clkOutMmcm(1)); + + U_RegGen : if REG_BUFF_EN_G generate + + U_BufIn : BUFR + port map ( + CE => '0', + CLR => '0', + I => clkIn, + O => clkInLoc); + + U_BufFb : BUFR + port map ( + CE => '0', + CLR => '0', + I => clkFbOut, + O => clkFbIn); + + U_BufOut : BUFR + port map ( + CE => '0', + CLR => '0', + I => clkOutMmcm(0), + O => clkOutLoc(0)); + + U_BufIo : BUFIO + port map ( + I => clkOutMmcm(1), + O => clkOutLoc(1)); + + end generate; + + U_GlbGen : if not REG_BUFF_EN_G generate + + U_BufIn : BUFG + port map ( + I => clkIn, + O => clkInLoc); + + U_BufFb : BUFG + port map ( + I => clkFbOut, + O => clkFbIn); + + U_BufOut : BUFG + port map ( + I => clkOutMmcm(0), + O => clkOutLoc(0)); + + U_BufIo : BUFG + port map ( + I => clkOutMmcm(1), + O => clkOutLoc(1)); + + end generate; + + genReset <= lockedLoc and (not rstIn); + + U_RstSync : entity work.RstSync + generic map ( + TPD_G => TPD_G, + IN_POLARITY_G => '0', + OUT_POLARITY_G => '1', + BYPASS_SYNC_G => false) + port map ( + clk => clkOutLoc(0), + asyncRst => genReset, + syncRst => clinkRst); + + clinkClk <= clkOutLoc(0); + clinkClk7x <= clkOutLoc(1); + +end rtl; diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd new file mode 100644 index 0000000000..9b2a2a2cc5 --- /dev/null +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -0,0 +1,311 @@ +------------------------------------------------------------------------------- +-- File : ClinkDataShift.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: +-- Block to de-serialize a block of 28 bits packed into 4 7-bit serial streams. +------------------------------------------------------------------------------- +-- 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; + +use work.StdRtlPkg.all; +use work.AxiLitePkg.all; +use work.ClinkPkg.all; + +library unisim; +use unisim.vcomponents.all; + +entity ClinkDataShift is + generic ( + TPD_G : time := 1 ns + XIL_DEVICE_G : string := "ULTRASCALE"); + port ( + -- Input clock and data + cblHalfP : inout slv(4 downto 0); + cblHalfM : inout slv(4 downto 0); + -- Async link reset + linkRst : in sl; + -- Delay clock, 200Mhz + dlyClk : in sl; + dlyRst : in sl; + -- Parallel Clock and reset Output, 85Mhz + clinkClk : out sl; + clinkRst : out sl; + -- Parallel clock and data output (clinkClk) + parData : out slv(27 downto 0); + parClock : out slv(6 downto 0); + -- Control inputs + delay : in slv(4 downto 0); + delayLd : in sl; + bitSlip : in sl; + -- Frequency Measurements + clkInFreq : out slv(31 downto 0); + clinkClkFreq : out slv(31 downto 0); + -- AXI-Lite Interface + sysClk : in sl; + sysRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end ClinkDataShift; + +architecture structure of ClinkDataShift is + + signal intClk : sl; + signal intRst : sl; + signal intClk4x : sl; + signal intClk1x : sl; + signal intDelay : slv(8 downto 0) := (others => '0'); + signal intLd : sl; + signal cblInDly : slv(4 downto 0); + signal cblIn : slv(4 downto 0); + signal rawIn : slv(4 downto 0); + signal serdes : Slv8Array(4 downto 0); + signal dataShift : Slv7Array(4 downto 0); + signal clkReset : sl; + + attribute IODELAY_GROUP : string; + +begin + + U_clkInFreq : entity work.SyncClockFreq + generic map ( + TPD_G => TPD_G, + REF_CLK_FREQ_G => 200.0E+6, + REFRESH_RATE_G => 1.0, + CNT_WIDTH_G => 32) + port map ( + -- Frequency Measurement (locClk domain) + freqOut => clkInFreq, + -- Clocks + clkIn => rawIn(0), + locClk => sysClk, + refClk => dlyClk); + + U_clinkClkFreq : entity work.SyncClockFreq + generic map ( + TPD_G => TPD_G, + REF_CLK_FREQ_G => 200.0E+6, + REFRESH_RATE_G => 1.0, + CNT_WIDTH_G => 32) + port map ( + -- Frequency Measurement (locClk domain) + freqOut => clinkClkFreq, + -- Clocks + clkIn => intClk, + locClk => sysClk, + refClk => dlyClk); + + -------------------------------------- + -- Clock Generation + -------------------------------------- + U_MMCM : entity work.ClockManagerUltraScale + generic map( + TPD_G => TPD_G, + TYPE_G => "MMCM", + INPUT_BUFG_G => true, + FB_BUFG_G => true, + RST_IN_POLARITY_G => '1', + NUM_CLOCKS_G => 3, + -- MMCM attributes + BANDWIDTH_G => "OPTIMIZED", + CLKIN_PERIOD_G => 10.0, -- 100 MHz + CLKFBOUT_MULT_F_G => 12.0, -- VCO = 1200MHz + CLKOUT0_DIVIDE_F_G => 12.0, -- 100 MHz (100 MHz x 7 = 600 Mb/s) + CLKOUT1_DIVIDE_G => 4, -- 300 MHz (300 MHz x DDR = 600 Mb/s) + CLKOUT2_DIVIDE_G => 8) -- 150 MHz (150 MHz x 4 = 600 Mb/s) + port map( + clkIn => rawIn(0), + rstIn => clkReset, + -- Clock Outputs + clkOut(0) => intClk, + clkOut(1) => intClk4x, + clkOut(2) => intClk1x, + -- Resets Outputs + rstOut(0) => intRst, + rstOut(1) => open, + rstOut(2) => open, + -- AXI-Lite Interface + axilClk => sysClk, + axilRst => sysRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave); + + -- Clock reset + clkReset <= linkRst or dlyRst; + + -------------------------------------- + -- Sync delay inputs + -------------------------------------- + U_SyncDelay : entity work.SynchronizerFifo + generic map ( + TPD_G => TPD_G, + DATA_WIDTH_G => 5) + port map ( + rst => intRst, + wr_clk => intClk, + wr_en => delayLd, + din => delay, + rd_clk => dlyClk, + valid => intLd, + dout => intDelay(8 downto 4)); + + -- Input buffer + U_InBuff : IBUFDS + port map( + IO => cblHalfP(0), + IOB => cblHalfM(0)); + I => '0', + O => cblIn(i), + + -------------------------------------- + -- Input Chain + -------------------------------------- + U_InputGen : for i in 0 to 4 generate + attribute IODELAY_GROUP of U_Delay : label is "CLINK_CORE"; + begin + + -- Input buffer + U_InBuff : IOBUFDS + port map( + I => '0', + O => cblIn(i), + T => '1', + IO => cblHalfP(i), + IOB => cblHalfM(i)); + + -- Each delay tap = 1/(32 * 2 * 200Mhz) = 78ps + -- Input rate = 85Mhz * 7 = 595Mhz = 1.68nS = 21.55 taps + U_Delay : IDELAYE3 + generic map ( + CASCADE => "NONE", -- Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE) + DELAY_FORMAT => "COUNT", -- Units of the DELAY_VALUE (COUNT, TIME) + DELAY_SRC => "IDATAIN", -- Delay input (DATAIN, IDATAIN) + DELAY_TYPE => "VAR_LOAD", -- Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD) + DELAY_VALUE => 0, -- Input delay value setting + IS_CLK_INVERTED => '0', -- Optional inversion for CLK + IS_RST_INVERTED => '0', -- Optional inversion for RST + REFCLK_FREQUENCY => 200.0, -- IDELAYCTRL clock input frequency in MHz (200.0-2667.0) + SIM_DEVICE => XIL_DEVICE_G, -- Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2) + UPDATE_MODE => "ASYNC") -- Determines when updates to the delay will take effect (ASYNC, MANUAL, SYNC) + port map ( + CASC_OUT => open, -- 1-bit output: Cascade delay output to ODELAY input cascade + CNTVALUEOUT => open, -- 9-bit output: Counter value output + DATAOUT => cblInDly(i), -- 1-bit output: Delayed data output + CASC_IN => '0', -- 1-bit input: Cascade delay input from slave ODELAY CASCADE_OUT + CASC_RETURN => '0', -- 1-bit input: Cascade delay returning from slave ODELAY DATAOUT + CE => '0', -- 1-bit input: Active high enable increment/decrement input + CLK => dlyClk, -- 1-bit input: Clock input + CNTVALUEIN => intDelay, -- 9-bit input: Counter value input + DATAIN => '0', -- 1-bit input: Data input from the logic + EN_VTC => '0', -- 1-bit input: Keep delay constant over VT + IDATAIN => cblIn(i), -- 1-bit input: Data input from the IOBUF + INC => '0', -- 1-bit input: Increment / Decrement tap delay input + LOAD => intLd, -- 1-bit input: Load DELAY_VALUE input + RST => '0'); -- 1-bit input: Asynchronous Reset to the DELAY_VALUE + + rawIn(i) <= cblInDly(i); + + -- Deserializer + U_Serdes : ISERDESE3 + generic map ( + DATA_WIDTH => 4, -- Parallel data width (4,8) + FIFO_ENABLE => "FALSE", -- Enables the use of the FIFO + FIFO_SYNC_MODE => "FALSE", -- Enables the use of internal 2-stage synchronizers on the FIFO + IS_CLK_B_INVERTED => '1', -- Optional inversion for CLK_B + IS_CLK_INVERTED => '0', -- Optional inversion for CLK + IS_RST_INVERTED => '0', -- Optional inversion for RST + SIM_DEVICE => XIL_DEVICE_G) -- Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2) + port map ( + Q => serdes(i), -- 8-bit registered output + CLK => intClk4x, -- 1-bit input: High-speed clock + CLK_B => intClk4x, -- 1-bit input: Inversion of High-speed clock CLK (IS_CLK_B_INVERTED='1') + CLKDIV => intClk1x, -- 1-bit input: Divided Clock + D => cblInDly(i), -- 1-bit input: Serial Data Input + RST => intRst, -- 1-bit input: Asynchronous Reset + FIFO_RD_CLK => '0', -- 1-bit input: FIFO read clock + FIFO_RD_EN => '0', -- 1-bit input: Enables reading the FIFO when asserted + FIFO_EMPTY => open); -- 1-bit output: FIFO empty flag + + U_Gearbox : entity work.AsyncGearbox + generic map ( + TPD_G => TPD_G, + SLAVE_WIDTH_G => 4, + MASTER_WIDTH_G => 7) + port map ( + slip => bitslip, + -- Slave Port + slaveClk => intClk1x, + slaveRst => '0', + slaveData => serdes(i), + -- Master Port + masterClk => intClk, + masterRst => '0', + masterData => dataShift(i)); + + end generate; + + ------------------------------------------------------- + -- Timing diagram from DS90CR288A data sheet + ------------------------------------------------------- + -- Lane T0 T1 T2 T3 T4 T5 T6 + -- 0 7 6 4 3 2 1 0 + -- 1 18 15 14 13 12 9 8 + -- 2 26 25 24 22 21 20 19 + -- 3 23 17 16 11 10 5 27 + -- + -- Iserdes Bits + -- 6 5 4 3 2 1 0 + ------------------------------------------------------- + parData(7) <= dataShift(1)(6); + parData(6) <= dataShift(1)(5); + parData(4) <= dataShift(1)(4); + parData(3) <= dataShift(1)(3); + parData(2) <= dataShift(1)(2); + parData(1) <= dataShift(1)(1); + parData(0) <= dataShift(1)(0); + + parData(18) <= dataShift(2)(6); + parData(15) <= dataShift(2)(5); + parData(14) <= dataShift(2)(4); + parData(13) <= dataShift(2)(3); + parData(12) <= dataShift(2)(2); + parData(9) <= dataShift(2)(1); + parData(8) <= dataShift(2)(0); + + parData(26) <= dataShift(3)(6); + parData(25) <= dataShift(3)(5); + parData(24) <= dataShift(3)(4); + parData(22) <= dataShift(3)(3); + parData(21) <= dataShift(3)(2); + parData(20) <= dataShift(3)(1); + parData(19) <= dataShift(3)(0); + + parData(23) <= dataShift(4)(6); + parData(17) <= dataShift(4)(5); + parData(16) <= dataShift(4)(4); + parData(11) <= dataShift(4)(3); + parData(10) <= dataShift(4)(2); + parData(5) <= dataShift(4)(1); + parData(27) <= dataShift(4)(0); + + parClock <= dataShift(0); + clinkClk <= intClk; + clinkRst <= intRst; + +end structure; + diff --git a/protocols/clink/hdl/ClinkCtrl.vhd b/protocols/clink/rtl/ClinkCtrl.vhd similarity index 100% rename from protocols/clink/hdl/ClinkCtrl.vhd rename to protocols/clink/rtl/ClinkCtrl.vhd diff --git a/protocols/clink/hdl/ClinkData.vhd b/protocols/clink/rtl/ClinkData.vhd similarity index 98% rename from protocols/clink/hdl/ClinkData.vhd rename to protocols/clink/rtl/ClinkData.vhd index 338837ba48..d21751fb82 100644 --- a/protocols/clink/hdl/ClinkData.vhd +++ b/protocols/clink/rtl/ClinkData.vhd @@ -29,7 +29,8 @@ use unisim.vcomponents.all; entity ClinkData is generic ( - TPD_G : time := 1 ns); + TPD_G : time := 1 ns; + XIL_DEVICE_G : string := "7SERIES"); port ( -- Cable Input cblHalfP : inout slv(4 downto 0); -- 8, 10, 11, 12, 9 @@ -101,7 +102,9 @@ begin -- DeSerializer ------------------------------- U_DataShift : entity work.ClinkDataShift - generic map (TPD_G => TPD_G) + generic map ( + TPD_G => TPD_G, + XIL_DEVICE_G => XIL_DEVICE_G) port map ( cblHalfP => cblHalfP, cblHalfM => cblHalfM, diff --git a/protocols/clink/hdl/ClinkFraming.vhd b/protocols/clink/rtl/ClinkFraming.vhd similarity index 100% rename from protocols/clink/hdl/ClinkFraming.vhd rename to protocols/clink/rtl/ClinkFraming.vhd diff --git a/protocols/clink/hdl/ClinkPkg.vhd b/protocols/clink/rtl/ClinkPkg.vhd similarity index 100% rename from protocols/clink/hdl/ClinkPkg.vhd rename to protocols/clink/rtl/ClinkPkg.vhd diff --git a/protocols/clink/hdl/ClinkReg.vhd b/protocols/clink/rtl/ClinkReg.vhd similarity index 100% rename from protocols/clink/hdl/ClinkReg.vhd rename to protocols/clink/rtl/ClinkReg.vhd diff --git a/protocols/clink/hdl/ClinkTop.vhd b/protocols/clink/rtl/ClinkTop.vhd similarity index 98% rename from protocols/clink/hdl/ClinkTop.vhd rename to protocols/clink/rtl/ClinkTop.vhd index 4f7f7956d6..0747a08cf9 100644 --- a/protocols/clink/hdl/ClinkTop.vhd +++ b/protocols/clink/rtl/ClinkTop.vhd @@ -28,6 +28,7 @@ use unisim.vcomponents.all; entity ClinkTop is generic ( TPD_G : time := 1 ns; + XIL_DEVICE_G : string := "7SERIES"; CHAN_COUNT_G : integer range 1 to 2 := 1; UART_READY_EN_G : boolean := true; COMMON_AXIL_CLK_G : boolean := false; -- true if axilClk=sysClk @@ -126,6 +127,8 @@ begin -- IDELAYCTRL Modules --------------------- U_IdelayCtrl : IDELAYCTRL + generic map ( + SIM_DEVICE => XIL_DEVICE_G) port map ( RDY => open, -- 1-bit output: Ready output REFCLK => dlyClk, -- 1-bit input: Reference clock input @@ -225,7 +228,9 @@ begin -- Connector 0, Half 1, Data X for Base,Medium,Full,Deca -------------------------------------------------------- U_Cbl0Half1 : entity work.ClinkData - generic map (TPD_G => TPD_G) + generic map ( + TPD_G => TPD_G, + XIL_DEVICE_G => XIL_DEVICE_G) port map ( cblHalfP => cbl0Half1P, cblHalfM => cbl0Half1M, diff --git a/protocols/clink/hdl/ClinkUart.vhd b/protocols/clink/rtl/ClinkUart.vhd similarity index 100% rename from protocols/clink/hdl/ClinkUart.vhd rename to protocols/clink/rtl/ClinkUart.vhd diff --git a/protocols/clink/hdl/ClinkUartThrottle.vhd b/protocols/clink/rtl/ClinkUartThrottle.vhd similarity index 100% rename from protocols/clink/hdl/ClinkUartThrottle.vhd rename to protocols/clink/rtl/ClinkUartThrottle.vhd diff --git a/protocols/clink/ruckus.tcl b/protocols/clink/ruckus.tcl index 6c97733ef6..358dcc604a 100644 --- a/protocols/clink/ruckus.tcl +++ b/protocols/clink/ruckus.tcl @@ -4,16 +4,22 @@ source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl # Get the family type set family [getFpgaFamily] +# Load Source Code +loadSource -dir "$::DIR_PATH/rtl" + +# Load Simulation +loadSource -sim_only -dir "$::DIR_PATH/tb" + if { ${family} == "artix7" || ${family} == "kintex7" || ${family} == "virtex7" || ${family} == "zynq" } { - - # Load Source Code - loadSource -dir "$::DIR_PATH/hdl" - - # Load Simulation - loadSource -sim_only -dir "$::DIR_PATH/sim" - + loadSource -dir "$::DIR_PATH/7Series" } +if { ${family} eq {kintexu} || + ${family} eq {kintexuplus} || + ${family} eq {virtexuplus} || + ${family} eq {zynquplus} } { + loadSource -dir "$::DIR_PATH/UltraScale" +} diff --git a/protocols/clink/sim/ClinkFramerTb.vhd b/protocols/clink/tb/ClinkFramerTb.vhd similarity index 100% rename from protocols/clink/sim/ClinkFramerTb.vhd rename to protocols/clink/tb/ClinkFramerTb.vhd From 5b52ff5b4fbcba830b868746ffe3215f090028a2 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 12:06:51 -0700 Subject: [PATCH 73/92] bug fix --- protocols/clink/UltraScale/ClinkDataShift.vhd | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd index 9b2a2a2cc5..b9ec74159b 100644 --- a/protocols/clink/UltraScale/ClinkDataShift.vhd +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -28,7 +28,7 @@ use unisim.vcomponents.all; entity ClinkDataShift is generic ( - TPD_G : time := 1 ns + TPD_G : time := 1 ns; XIL_DEVICE_G : string := "ULTRASCALE"); port ( -- Input clock and data @@ -164,14 +164,6 @@ begin valid => intLd, dout => intDelay(8 downto 4)); - -- Input buffer - U_InBuff : IBUFDS - port map( - IO => cblHalfP(0), - IOB => cblHalfM(0)); - I => '0', - O => cblIn(i), - -------------------------------------- -- Input Chain -------------------------------------- From 87a1bce28ac68376e9d1fe6008fd55b05309778c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 12:24:25 -0700 Subject: [PATCH 74/92] more bug fixes --- dsp/logic/DspXor.vhd | 2 +- protocols/clink/UltraScale/ClinkDataShift.vhd | 6 +++--- xilinx/UltraScale/general/rtl/InputBufferReg.vhd | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dsp/logic/DspXor.vhd b/dsp/logic/DspXor.vhd index 0b2c453c0e..3405292ba0 100644 --- a/dsp/logic/DspXor.vhd +++ b/dsp/logic/DspXor.vhd @@ -67,7 +67,7 @@ begin a := signed(ain); -- Process the data - v.p := uXor(a); + v.p := xor(a); -- Register the variable for next clock cycle rin <= v; diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd index b9ec74159b..bf0421f68c 100644 --- a/protocols/clink/UltraScale/ClinkDataShift.vhd +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -125,7 +125,7 @@ begin CLKFBOUT_MULT_F_G => 12.0, -- VCO = 1200MHz CLKOUT0_DIVIDE_F_G => 12.0, -- 100 MHz (100 MHz x 7 = 600 Mb/s) CLKOUT1_DIVIDE_G => 4, -- 300 MHz (300 MHz x DDR = 600 Mb/s) - CLKOUT2_DIVIDE_G => 8) -- 150 MHz (150 MHz x 4 = 600 Mb/s) + CLKOUT2_DIVIDE_G => 16) -- 75 MHz ( 75 MHz x 8 = 600 Mb/s) port map( clkIn => rawIn(0), rstIn => clkReset, @@ -215,7 +215,7 @@ begin -- Deserializer U_Serdes : ISERDESE3 generic map ( - DATA_WIDTH => 4, -- Parallel data width (4,8) + DATA_WIDTH => 8, -- Parallel data width (4,8) FIFO_ENABLE => "FALSE", -- Enables the use of the FIFO FIFO_SYNC_MODE => "FALSE", -- Enables the use of internal 2-stage synchronizers on the FIFO IS_CLK_B_INVERTED => '1', -- Optional inversion for CLK_B @@ -236,7 +236,7 @@ begin U_Gearbox : entity work.AsyncGearbox generic map ( TPD_G => TPD_G, - SLAVE_WIDTH_G => 4, + SLAVE_WIDTH_G => 8, MASTER_WIDTH_G => 7) port map ( slip => bitslip, diff --git a/xilinx/UltraScale/general/rtl/InputBufferReg.vhd b/xilinx/UltraScale/general/rtl/InputBufferReg.vhd index 0b5eace70b..f784a62ec3 100644 --- a/xilinx/UltraScale/general/rtl/InputBufferReg.vhd +++ b/xilinx/UltraScale/general/rtl/InputBufferReg.vhd @@ -68,7 +68,7 @@ begin Q2 => Q2, -- 1-bit output: Registered parallel output 2 C => C, -- 1-bit input: High-speed clock CB => CB, -- 1-bit input: Inversion of High-speed clock C - D => D, -- 1-bit input: Serial Data Input + D => inputSig, -- 1-bit input: Serial Data Input R => R); -- 1-bit input: Active High Async Reset CB <= not(C); From 0d8487360db0a8d31de1bf62086cbcf1672576d6 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 12:32:20 -0700 Subject: [PATCH 75/92] redoing MMCM configuration because Ultrascale+ doesn't support an MMCM VCO of 625 MHz --- .../Sgmii88E1111LvdsUltraScale.vhd | 13 ++--- .../rtl/GigEthLvdsUltraScaleWrapper.vhd | 47 ++++++++++--------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 74cef00d30..7545df2023 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -180,16 +180,9 @@ begin U_1GigE : entity work.GigEthLvdsUltraScaleWrapper generic map ( - TPD_G => TPD_G, - -- DMA/MAC Configurations - NUM_LANE_G => 1, - -- MMCM Configuration - USE_REFCLK_G => false, - CLKIN_PERIOD_G => 1.6, -- 625.0 MHz - DIVCLK_DIVIDE_G => 2, -- 312.5 MHz - CLKFBOUT_MULT_F_G => 2.0, -- VCO: 625 MHz - -- AXI Streaming Configurations - AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) + TPD_G => TPD_G, + NUM_LANE_G => 1, + AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) port map ( -- Local Configurations localMac(0) => localMac, diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd index bacd46d1d6..0fad43594b 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd @@ -34,7 +34,7 @@ entity GigEthLvdsUltraScaleWrapper is -- Clocking Configurations USE_REFCLK_G : boolean := false; -- FALSE: sgmiiClkP/N, TRUE: sgmiiRefClk CLKIN_PERIOD_G : real := 1.6; - DIVCLK_DIVIDE_G : positive := 2; + DIVCLK_DIVIDE_G : positive := 1; CLKFBOUT_MULT_F_G : real := 2.0; -- AXI-Lite Configurations EN_AXI_REG_G : boolean := false; @@ -96,6 +96,7 @@ architecture mapping of GigEthLvdsUltraScaleWrapper is signal sysRst312 : sl; signal sysClk625 : sl; signal sysRst625 : sl; + signal sysClkNB4 : sl; signal sysClkNB : slv(6 downto 0); signal sysClkB : slv(6 downto 0); signal sysRst : slv(6 downto 0); @@ -197,17 +198,14 @@ begin -- the BUFG in the feedback chain. U_MMCM : MMCME3_BASE generic map( - CLKOUT0_DIVIDE_F => 5.0, - CLKOUT1_DIVIDE => 2, - CLKOUT2_DIVIDE => 1, - CLKOUT3_DIVIDE => 50, - CLKOUT4_DIVIDE => 50, - CLKOUT4_CASCADE => "TRUE", - CLKOUT6_DIVIDE => 10, - CLKFBOUT_MULT_F => CLKFBOUT_MULT_F_G, + CLKIN1_PERIOD => CLKIN_PERIOD_G, DIVCLK_DIVIDE => DIVCLK_DIVIDE_G, - CLKIN1_PERIOD => CLKIN_PERIOD_G - ) + CLKFBOUT_MULT_F => CLKFBOUT_MULT_F_G, -- 1.25GHz + CLKOUT0_DIVIDE_F => 10.0, -- 125 MHz + CLKOUT1_DIVIDE => 4, -- 312.5 MHz + CLKOUT2_DIVIDE => 2, -- 625 MHz + CLKOUT3_DIVIDE => 100, -- 12.5 MHz + CLKOUT4_DIVIDE => 125) -- 10 MHz port map ( CLKIN1 => refClk, RST => refRst, @@ -217,30 +215,35 @@ begin CLKOUT1 => sysClkNB(1), CLKOUT2 => sysClkNB(2), CLKOUT3 => sysClkNB(3), - CLKOUT4 => sysClkNB(4), - CLKOUT5 => sysClkNB(5), - CLKOUT6 => sysClkNB(6), + CLKOUT4 => sysClkNB4, + CLKOUT5 => open, + CLKOUT6 => open, LOCKED => locked, - PWRDWN => '0' - ); + PWRDWN => '0'); + U_Bufg160 : BUFGCE_DIV + generic map ( + BUFGCE_DIVIDE => 8) + port map ( + I => sysClkNB4, -- 10 MHz + CE => '1', + CLR => '0', + O => sysClkNB(4)); -- 1.25 MHz = 10MHz / 8 + GEN_BUFG : for i in 0 to NUM_CLOCKS_C - 1 generate U_BUFG_125 : BUFG port map ( I => sysClkNB(i), - O => sysClkB(i) - ); + O => sysClkB(i)); U_RESET : entity work.RstSync generic map ( TPD_G => TPD_G, - IN_POLARITY_G => '0' - ) + IN_POLARITY_G => '0') port map ( clk => sysClkB(i), asyncRst => locked, - syncRst => sysRst(i) - ); + syncRst => sysRst(i)); end generate; sysClk125 <= sysClkB(0); From 48d6fca0daa54e3c1e9151424a363e94191ef589 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 12:33:52 -0700 Subject: [PATCH 76/92] fixed component name --- .../lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd index 0fad43594b..cf3acf77bc 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd @@ -221,7 +221,7 @@ begin LOCKED => locked, PWRDWN => '0'); - U_Bufg160 : BUFGCE_DIV + U_Bufg_1_25MHz : BUFGCE_DIV generic map ( BUFGCE_DIVIDE => 8) port map ( From fd4a8b9484211a18b77da74b9ac63ef48c1aa72d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 5 Apr 2019 12:38:22 -0700 Subject: [PATCH 77/92] Change reload timer back to an SLV so that axi procedure works on it --- axi/axi-lite/rtl/AxiVersionLegacy.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/axi/axi-lite/rtl/AxiVersionLegacy.vhd b/axi/axi-lite/rtl/AxiVersionLegacy.vhd index 3c367ec11c..4638c025ed 100644 --- a/axi/axi-lite/rtl/AxiVersionLegacy.vhd +++ b/axi/axi-lite/rtl/AxiVersionLegacy.vhd @@ -75,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); - reloadTimer : natural range 0 to AUTO_RELOAD_TIME_G; + reloadTimer : slv(31 downto 0); userReset : sl; fpgaReload : sl; haltReload : sl; @@ -88,7 +88,7 @@ architecture rtl of AxiVersionLegacy is upTimeCnt => (others => '0'), timer => 0, scratchPad => (others => '0'), - reloadTimer => 0, + reloadTimer => (others => '0'), userReset => '1', -- Asserted on powerup fpgaReload => '0', haltReload => '0', From 473556167ad4c359dc99056c1babdb37dc49b2dc Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 13:08:43 -0700 Subject: [PATCH 78/92] Doxygen doesn't support VHDL-2008 xor yet --- generateDocumentationAndDeploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/generateDocumentationAndDeploy.sh b/generateDocumentationAndDeploy.sh index a00434be1b..db81602698 100644 --- a/generateDocumentationAndDeploy.sh +++ b/generateDocumentationAndDeploy.sh @@ -94,6 +94,7 @@ echo "INPUT = $TRAVIS_BUILD_DIR" >> $DOXYFILE # Update the EXCLUDE configuration echo "EXCLUDE = $TRAVIS_BUILD_DIR/protocols/i2c/rtl/orig" >> $DOXYFILE echo "EXCLUDE += $TRAVIS_BUILD_DIR/base/vhdl-libs" >> $DOXYFILE +echo "EXCLUDE += $TRAVIS_BUILD_DIR/dsp/logic/DspXor.vhd" >> $DOXYFILE # Doxygen doesn't support VHDL-2008 xor yet # Updating the warning message configuration echo "WARN_IF_UNDOCUMENTED = NO" >> $DOXYFILE From d4847150b4bf6934d0e04fa251e2580b438f8fde Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 5 Apr 2019 15:39:13 -0700 Subject: [PATCH 79/92] exposing MMCM generics to top level --- .../lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 7545df2023..b6b9c4fa01 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -26,6 +26,9 @@ entity Sgmii88E1111LvdsUltraScale is generic ( TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; + CLKIN_PERIOD_G : real := 1.6; + DIVCLK_DIVIDE_G : positive := 2; + CLKFBOUT_MULT_F_G : real := 4.0; PHY_G : natural range 0 to 31 := 7; AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( @@ -180,9 +183,12 @@ begin U_1GigE : entity work.GigEthLvdsUltraScaleWrapper generic map ( - TPD_G => TPD_G, - NUM_LANE_G => 1, - AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) + TPD_G => TPD_G, + NUM_LANE_G => 1, + CLKIN_PERIOD_G => CLKIN_PERIOD_G, + DIVCLK_DIVIDE_G => DIVCLK_DIVIDE_G, + CLKFBOUT_MULT_F_G => CLKFBOUT_MULT_F_G, + AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) port map ( -- Local Configurations localMac(0) => localMac, From 62fc8d8d2ba7505ce768a77c2d06e617f6635351 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 8 Apr 2019 09:31:41 -0700 Subject: [PATCH 80/92] EN_VTC=High Enables IDELAYCTRL to keep delay constant over VT --- protocols/clink/UltraScale/ClinkDataShift.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd index bf0421f68c..4bb08ab6ff 100644 --- a/protocols/clink/UltraScale/ClinkDataShift.vhd +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -185,7 +185,7 @@ begin U_Delay : IDELAYE3 generic map ( CASCADE => "NONE", -- Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE) - DELAY_FORMAT => "COUNT", -- Units of the DELAY_VALUE (COUNT, TIME) + DELAY_FORMAT => "TIME", -- Units of the DELAY_VALUE (COUNT, TIME) DELAY_SRC => "IDATAIN", -- Delay input (DATAIN, IDATAIN) DELAY_TYPE => "VAR_LOAD", -- Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD) DELAY_VALUE => 0, -- Input delay value setting @@ -204,7 +204,7 @@ begin CLK => dlyClk, -- 1-bit input: Clock input CNTVALUEIN => intDelay, -- 9-bit input: Counter value input DATAIN => '0', -- 1-bit input: Data input from the logic - EN_VTC => '0', -- 1-bit input: Keep delay constant over VT + EN_VTC => '1', -- 1-bit input: Keep delay constant over VT IDATAIN => cblIn(i), -- 1-bit input: Data input from the IOBUF INC => '0', -- 1-bit input: Increment / Decrement tap delay input LOAD => intLd, -- 1-bit input: Load DELAY_VALUE input From f7b3d62b7f8048e855fbd45a8b4e1bac5f9898e3 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 8 Apr 2019 11:21:59 -0700 Subject: [PATCH 81/92] adding clock enable support to EthMac's GMII interface --- .../Sgmii88E1111LvdsUltraScale.vhd | 12 +- ethernet/EthMacCore/rtl/EthMacRx.vhd | 2 + ethernet/EthMacCore/rtl/EthMacRxImport.vhd | 2 + .../EthMacCore/rtl/EthMacRxImportGmii.vhd | 133 +++++---- ethernet/EthMacCore/rtl/EthMacTop.vhd | 3 + ethernet/EthMacCore/rtl/EthMacTx.vhd | 2 + ethernet/EthMacCore/rtl/EthMacTxExport.vhd | 2 + .../EthMacCore/rtl/EthMacTxExportGmii.vhd | 220 +++++++------- .../rtl/GigEthLvdsClockEnable.vhd | 125 ++++++++ .../lvdsUltraScale/rtl/GigEthLvdsClockMux.vhd | 54 ---- .../rtl/GigEthLvdsUltraScale.vhd | 8 +- .../rtl/GigEthLvdsUltraScaleWrapper.vhd | 276 ++++++------------ ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl | 15 - .../lvdsUltraScale/xdc/GigEthLvdsClockMux.xdc | 20 -- .../xdc/GigEthLvdsUltraScaleWrapper.xdc | 22 -- 15 files changed, 411 insertions(+), 485 deletions(-) create mode 100644 ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockEnable.vhd delete mode 100644 ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockMux.vhd delete mode 100644 ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsClockMux.xdc delete mode 100644 ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsUltraScaleWrapper.xdc diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index b6b9c4fa01..7545df2023 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -26,9 +26,6 @@ entity Sgmii88E1111LvdsUltraScale is generic ( TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; - CLKIN_PERIOD_G : real := 1.6; - DIVCLK_DIVIDE_G : positive := 2; - CLKFBOUT_MULT_F_G : real := 4.0; PHY_G : natural range 0 to 31 := 7; AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( @@ -183,12 +180,9 @@ begin U_1GigE : entity work.GigEthLvdsUltraScaleWrapper generic map ( - TPD_G => TPD_G, - NUM_LANE_G => 1, - CLKIN_PERIOD_G => CLKIN_PERIOD_G, - DIVCLK_DIVIDE_G => DIVCLK_DIVIDE_G, - CLKFBOUT_MULT_F_G => CLKFBOUT_MULT_F_G, - AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) + TPD_G => TPD_G, + NUM_LANE_G => 1, + AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) port map ( -- Local Configurations localMac(0) => localMac, diff --git a/ethernet/EthMacCore/rtl/EthMacRx.vhd b/ethernet/EthMacCore/rtl/EthMacRx.vhd index 28c4205e14..08d3534d37 100644 --- a/ethernet/EthMacCore/rtl/EthMacRx.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRx.vhd @@ -40,6 +40,7 @@ entity EthMacRx is VLAN_VID_G : Slv12Array := (0 => x"001")); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- Primary Interface @@ -90,6 +91,7 @@ begin PHY_TYPE_G => PHY_TYPE_G) port map ( -- Clock and reset + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- AXIS Interface diff --git a/ethernet/EthMacCore/rtl/EthMacRxImport.vhd b/ethernet/EthMacCore/rtl/EthMacRxImport.vhd index 16bf6136b0..62cc8c2a13 100644 --- a/ethernet/EthMacCore/rtl/EthMacRxImport.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRxImport.vhd @@ -28,6 +28,7 @@ entity EthMacRxImport is PHY_TYPE_G : string := "XGMII"); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- AXIS Interface @@ -98,6 +99,7 @@ begin TPD_G => TPD_G) port map ( -- Clock and Reset + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- AXIS Interface diff --git a/ethernet/EthMacCore/rtl/EthMacRxImportGmii.vhd b/ethernet/EthMacCore/rtl/EthMacRxImportGmii.vhd index 065de94f03..b406ce3def 100644 --- a/ethernet/EthMacCore/rtl/EthMacRxImportGmii.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRxImportGmii.vhd @@ -27,6 +27,7 @@ entity EthMacRxImportGmii is TPD_G : time := 1 ns); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- AXIS Interface @@ -115,21 +116,22 @@ begin CASCADE_SIZE_G => 1, FIFO_ADDR_WIDTH_G => 4, -- AXI Stream Port Configurations - SLAVE_AXI_CONFIG_G => AXI_CONFIG_C, -- 8-bit AXI stream interface + SLAVE_AXI_CONFIG_G => AXI_CONFIG_C, -- 8-bit AXI stream interface MASTER_AXI_CONFIG_G => EMAC_AXIS_CONFIG_C) -- 128-bit AXI stream interface port map ( -- Slave Port sAxisClk => ethClk, sAxisRst => ethRst, - sAxisMaster => macMaster, -- 8-bit AXI stream interface + sAxisMaster => macMaster, -- 8-bit AXI stream interface sAxisSlave => open, -- Master Port mAxisClk => ethClk, mAxisRst => ethRst, - mAxisMaster => macIbMaster, -- 128-bit AXI stream interface - mAxisSlave => AXI_STREAM_SLAVE_FORCE_C); + mAxisMaster => macIbMaster, -- 128-bit AXI stream interface + mAxisSlave => AXI_STREAM_SLAVE_FORCE_C); - comb : process (crcIn, crcOut, ethRst, gmiiRxDv, gmiiRxEr, gmiiRxd, phyReady, r) is + comb : process (crcIn, crcOut, ethClkEn, ethRst, gmiiRxDv, gmiiRxEr, + gmiiRxd, phyReady, r) is variable v : RegType; begin -- Latch the current value @@ -145,69 +147,74 @@ begin v.macMaster.tUser := (others => '0'); v.macMaster.tKeep := (others => '1'); - -- Delay data to avoid sending the CRC - v.macData(63 downto 0) := r.macData(55 downto 0) & gmiiRxd; + -- Check for clock enable + if (ethClkEn = '1') then - -- Delay the GMII valid for start up sequencing - v.delRxDvSr := r.delRxDvSr(6 downto 0) & r.delRxDv; + -- Delay data to avoid sending the CRC + v.macData(63 downto 0) := r.macData(55 downto 0) & gmiiRxd; - -- Check for CRC reset - v.crcReset := r.delRxDvSr(2) or ethRst or (not phyReady); + -- Delay the GMII valid for start up sequencing + v.delRxDvSr := r.delRxDvSr(6 downto 0) & r.delRxDv; - -- State Machine - case r.state is - ---------------------------------------------------------------------- - when WAIT_SFD_S => - v.sof := '1'; - if ((gmiiRxd = SFD_C) and (gmiiRxDv = '1') and (gmiiRxEr = '0') and (phyReady = '1')) then - v.delRxDv := '1'; - v.state := WAIT_DATA_S; - end if; - ---------------------------------------------------------------------- - when WAIT_DATA_S => - if (gmiiRxDv = '0') or (gmiiRxEr = '1') or (phyReady = '0') then - v.state := WAIT_SFD_S; - elsif (r.delRxDvSr(3) = '1') then - v.state := GET_DATA_S; - end if; - ---------------------------------------------------------------------- - when GET_DATA_S => - if ((gmiiRxEr = '1') and (gmiiRxDv = '1')) or (phyReady = '0') then -- Error + -- Check for CRC reset + v.crcReset := r.delRxDvSr(2) or ethRst or (not phyReady); + + -- State Machine + case r.state is + ---------------------------------------------------------------------- + when WAIT_SFD_S => + v.sof := '1'; + if ((gmiiRxd = SFD_C) and (gmiiRxDv = '1') and (gmiiRxEr = '0') and (phyReady = '1')) then + v.delRxDv := '1'; + v.state := WAIT_DATA_S; + end if; + ---------------------------------------------------------------------- + when WAIT_DATA_S => + if (gmiiRxDv = '0') or (gmiiRxEr = '1') or (phyReady = '0') then + v.state := WAIT_SFD_S; + elsif (r.delRxDvSr(3) = '1') then + v.state := GET_DATA_S; + end if; + ---------------------------------------------------------------------- + when GET_DATA_S => + if ((gmiiRxEr = '1') and (gmiiRxDv = '1')) or (phyReady = '0') then -- Error + v.macMaster.tvalid := '1'; + v.macMaster.tlast := '1'; + axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_EOFE_BIT_C, '1', 0); + v.state := WAIT_SFD_S; + else + v.crcDataValid := '1'; + v.macMaster.tvalid := gmiiRxDv; + v.macMaster.tdata(7 downto 0) := r.macData(39 downto 32); + if (gmiiRxDv = '0') then + v.state := DELAY0_S; + end if; + if (r.sof = '1') then + axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_SOF_BIT_C, '1', 0); + v.sof := '0'; + end if; + end if; + ---------------------------------------------------------------------- + when DELAY0_S => + v.state := DELAY1_S; + ---------------------------------------------------------------------- + when DELAY1_S => + v.state := CRC_S; + ---------------------------------------------------------------------- + when CRC_S => v.macMaster.tvalid := '1'; v.macMaster.tlast := '1'; - axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_EOFE_BIT_C, '1', 0); - v.state := WAIT_SFD_S; - else - v.crcDataValid := '1'; - v.macMaster.tvalid := gmiiRxDv; - v.macMaster.tdata(7 downto 0) := r.macData(39 downto 32); - if (gmiiRxDv = '0') then - v.state := DELAY0_S; + if (crcIn /= crcOut) then + v.rxCrcError := '1'; + axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_EOFE_BIT_C, '1', 0); + else + v.rxCountEn := '1'; end if; - if (r.sof = '1') then - axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_SOF_BIT_C, '1', 0); - v.sof := '0'; - end if; - end if; - ---------------------------------------------------------------------- - when DELAY0_S => - v.state := DELAY1_S; - ---------------------------------------------------------------------- - when DELAY1_S => - v.state := CRC_S; + v.state := WAIT_SFD_S; ---------------------------------------------------------------------- - when CRC_S => - v.macMaster.tvalid := '1'; - v.macMaster.tlast := '1'; - if (crcIn /= crcOut) then - v.rxCrcError := '1'; - axiStreamSetUserBit(AXI_CONFIG_C, v.macMaster, EMAC_EOFE_BIT_C, '1', 0); - else - v.rxCountEn := '1'; - end if; - v.state := WAIT_SFD_S; - ---------------------------------------------------------------------- - end case; + end case; + + end if; -- Reset if (ethRst = '1') then @@ -221,7 +228,7 @@ begin macMaster <= r.macMaster; rxCountEn <= r.rxCountEn; rxCrcError <= r.rxCrcError; - + end process comb; seq : process (ethClk) is @@ -244,6 +251,6 @@ begin crcDataValid => r.crcDataValid, crcDataWidth => "000", crcIn => r.macData(47 downto 40), - crcReset => r.crcReset); + crcReset => r.crcReset); end rtl; diff --git a/ethernet/EthMacCore/rtl/EthMacTop.vhd b/ethernet/EthMacCore/rtl/EthMacTop.vhd index 0f5fb951df..f416ca6756 100644 --- a/ethernet/EthMacCore/rtl/EthMacTop.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTop.vhd @@ -55,6 +55,7 @@ entity EthMacTop is VLAN_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( -- Core Clock and Reset + ethClkEn : in sl := '1'; ethClk : in sl; ethRst : in sl; -- Primary Interface @@ -194,6 +195,7 @@ begin VLAN_VID_G => VLAN_VID_G) port map ( -- Clocks + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- Primary Interface @@ -268,6 +270,7 @@ begin VLAN_VID_G => VLAN_VID_G) port map ( -- Clock and Reset + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- Primary Interface diff --git a/ethernet/EthMacCore/rtl/EthMacTx.vhd b/ethernet/EthMacCore/rtl/EthMacTx.vhd index 76303b098b..cfd9b297bf 100644 --- a/ethernet/EthMacCore/rtl/EthMacTx.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTx.vhd @@ -40,6 +40,7 @@ entity EthMacTx is VLAN_VID_G : Slv12Array := (0 => x"001")); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- Primary Interface @@ -210,6 +211,7 @@ begin PHY_TYPE_G => PHY_TYPE_G) port map ( -- Clock and reset + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- AXIS Interface diff --git a/ethernet/EthMacCore/rtl/EthMacTxExport.vhd b/ethernet/EthMacCore/rtl/EthMacTxExport.vhd index ff4f5939f8..e1ec2ba188 100644 --- a/ethernet/EthMacCore/rtl/EthMacTxExport.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTxExport.vhd @@ -27,6 +27,7 @@ entity EthMacTxExport is PHY_TYPE_G : string := "XGMII"); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- AXIS Interface @@ -118,6 +119,7 @@ begin TPD_G => TPD_G) port map ( -- Clock and Reset + ethClkEn => ethClkEn, ethClk => ethClk, ethRst => ethRst, -- AXIS Interface diff --git a/ethernet/EthMacCore/rtl/EthMacTxExportGmii.vhd b/ethernet/EthMacCore/rtl/EthMacTxExportGmii.vhd index 55393582ef..fbb9378eaa 100644 --- a/ethernet/EthMacCore/rtl/EthMacTxExportGmii.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTxExportGmii.vhd @@ -27,6 +27,7 @@ entity EthMacTxExportGmii is TPD_G : time := 1 ns); port ( -- Clock and Reset + ethClkEn : in sl; ethClk : in sl; ethRst : in sl; -- AXIS Interface @@ -138,7 +139,7 @@ begin mAxisMaster => macMaster, -- 8-bit AXI stream interface mAxisSlave => macSlave); - comb : process (crcOut, ethRst, macMaster, phyReady, r) is + comb : process (crcOut, ethClkEn, ethRst, macMaster, phyReady, r) is variable v : RegType; begin -- Latch the current value @@ -151,117 +152,122 @@ begin v.txUnderRun := '0'; v.txLinkNotReady := '0'; - -- State Machine - case r.state is - ---------------------------------------------------------------------- - when IDLE_S => - -- Reset the flags - v.crcReset := '1'; - v.txCount := x"00"; - v.txData := x"55"; -- Preset to PREAMBLE CHAR - v.gmiiTxd := x"00"; - v.gmiiTxEn := '0'; - v.gmiiTxEr := '0'; - -- Wait for start flag - if ((macMaster.tValid = '1') and (ethRst = '0')) then - -- Phy is ready - if phyReady = '1' then - v.state := TX_PREAMBLE_S; - -- Phy is not ready dump data + -- Check for clock enable + if (ethClkEn = '1') then + + -- State Machine + case r.state is + ---------------------------------------------------------------------- + when IDLE_S => + -- Reset the flags + v.crcReset := '1'; + v.txCount := x"00"; + v.txData := x"55"; -- Preset to PREAMBLE CHAR + v.gmiiTxd := x"00"; + v.gmiiTxEn := '0'; + v.gmiiTxEr := '0'; + -- Wait for start flag + if ((macMaster.tValid = '1') and (ethRst = '0')) then + -- Phy is ready + if phyReady = '1' then + v.state := TX_PREAMBLE_S; + -- Phy is not ready dump data + else + v.txLinkNotReady := '1'; + v.state := DUMP_S; + end if; + end if; + ---------------------------------------------------------------------- + when TX_PREAMBLE_S => + v.crcReset := '0'; + v.gmiiTxEn := '1'; + v.gmiiTxd := r.txData; + if (r.txCount = x"06") then + v.txCount := x"00"; + v.txData := x"D5"; -- Set to SFD char + v.state := TX_DATA_S; else - v.txLinkNotReady := '1'; - v.state := DUMP_S; + v.txCount := r.txCount +1; + v.txData := x"55"; -- Set to PREAMBLE char end if; - end if; - ---------------------------------------------------------------------- - when TX_PREAMBLE_S => - v.crcReset := '0'; - v.gmiiTxEn := '1'; - v.gmiiTxd := r.txData; - if (r.txCount = x"06") then - v.txCount := x"00"; - v.txData := x"D5"; -- Set to SFD char - v.state := TX_DATA_S; - else - v.txCount := r.txCount +1; - v.txData := x"55"; -- Set to PREAMBLE char - end if; - ---------------------------------------------------------------------- - when TX_DATA_S => - v.macSlave.tReady := '1'; - v.crcDataValid := '1'; - v.crcIn := macMaster.tdata(7 downto 0); - v.txData := macMaster.tdata(7 downto 0); - v.gmiiTxd := r.txData; - if (r.txCount < x"3C") then -- Minimum frame of 60B (= 84B - 8B Preamble - 4B CRC - 12B intergap) - v.txCount := r.txCount + 1; - end if; - if (macMaster.tValid = '1') then - if (macMaster.tlast = '1') then - if (v.txCount = x"3C") then - v.state := TX_CRC_S; - else - v.state := PAD_S; + ---------------------------------------------------------------------- + when TX_DATA_S => + v.macSlave.tReady := '1'; + v.crcDataValid := '1'; + v.crcIn := macMaster.tdata(7 downto 0); + v.txData := macMaster.tdata(7 downto 0); + v.gmiiTxd := r.txData; + if (r.txCount < x"3C") then -- Minimum frame of 60B (= 84B - 8B Preamble - 4B CRC - 12B intergap) + v.txCount := r.txCount + 1; + end if; + if (macMaster.tValid = '1') then + if (macMaster.tlast = '1') then + if (v.txCount = x"3C") then + v.state := TX_CRC_S; + else + v.state := PAD_S; + end if; end if; + else + v.gmiiTxEr := '1'; + v.txUnderRun := '1'; + v.state := DUMP_S; + end if; + ---------------------------------------------------------------------- + when PAD_S => + v.crcDataValid := '1'; + v.crcIn := x"00"; + v.txData := x"00"; + v.gmiiTxd := r.txData; + if (r.txCount < x"3C") then + v.txCount := v.txCount + 1; + else + v.state := TX_CRC_S; + end if; + ---------------------------------------------------------------------- + when TX_CRC_S => + v.gmiiTxd := r.txData; + v.state := TX_CRC0_S; + ---------------------------------------------------------------------- + when TX_CRC0_S => + v.gmiitxd := crcOut(31 downto 24); + v.state := TX_CRC1_S; + ---------------------------------------------------------------------- + when TX_CRC1_S => + v.gmiitxd := crcOut(23 downto 16); + v.state := TX_CRC2_S; + ---------------------------------------------------------------------- + when TX_CRC2_S => + v.gmiitxd := crcOut(15 downto 8); + v.state := TX_CRC3_S; + ---------------------------------------------------------------------- + when TX_CRC3_S => + v.txCountEn := '1'; + v.gmiitxd := crcOut(7 downto 0); + v.txCount := x"00"; + v.state := INTERGAP_S; + ---------------------------------------------------------------------- + when DUMP_S => + v.gmiiTxEn := '0'; + v.gmiiTxd := x"00"; + v.macSlave.tReady := '1'; + v.txCount := x"00"; + if ((macMaster.tValid = '1') and (macMaster.tlast = '1')) then + v.state := INTERGAP_S; + end if; + ---------------------------------------------------------------------- + when INTERGAP_S => + v.gmiiTxEn := '0'; + v.gmiiTxd := x"00"; + v.txCount := r.txCount +1; + if r.txCount = x"0A" then -- 12 Octels (11 in INTERGAP_S + 1 in IDLE_S) + v.txCount := x"00"; + v.state := IDLE_S; end if; - else - v.gmiiTxEr := '1'; - v.txUnderRun := '1'; - v.state := DUMP_S; - end if; - ---------------------------------------------------------------------- - when PAD_S => - v.crcDataValid := '1'; - v.crcIn := x"00"; - v.txData := x"00"; - v.gmiiTxd := r.txData; - if (r.txCount < x"3C") then - v.txCount := v.txCount + 1; - else - v.state := TX_CRC_S; - end if; - ---------------------------------------------------------------------- - when TX_CRC_S => - v.gmiiTxd := r.txData; - v.state := TX_CRC0_S; - ---------------------------------------------------------------------- - when TX_CRC0_S => - v.gmiitxd := crcOut(31 downto 24); - v.state := TX_CRC1_S; - ---------------------------------------------------------------------- - when TX_CRC1_S => - v.gmiitxd := crcOut(23 downto 16); - v.state := TX_CRC2_S; - ---------------------------------------------------------------------- - when TX_CRC2_S => - v.gmiitxd := crcOut(15 downto 8); - v.state := TX_CRC3_S; - ---------------------------------------------------------------------- - when TX_CRC3_S => - v.txCountEn := '1'; - v.gmiitxd := crcOut(7 downto 0); - v.txCount := x"00"; - v.state := INTERGAP_S; - ---------------------------------------------------------------------- - when DUMP_S => - v.gmiiTxEn := '0'; - v.gmiiTxd := x"00"; - v.macSlave.tReady := '1'; - v.txCount := x"00"; - if ((macMaster.tValid = '1') and (macMaster.tlast = '1')) then - v.state := INTERGAP_S; - end if; ---------------------------------------------------------------------- - when INTERGAP_S => - v.gmiiTxEn := '0'; - v.gmiiTxd := x"00"; - v.txCount := r.txCount +1; - if r.txCount = x"0A" then -- 12 Octels (11 in INTERGAP_S + 1 in IDLE_S) - v.txCount := x"00"; - v.state := IDLE_S; - end if; - ---------------------------------------------------------------------- - end case; + end case; + + end if; -- Combinatorial outputs before the reset macSlave <= v.macSlave; diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockEnable.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockEnable.vhd new file mode 100644 index 0000000000..7500d9eab3 --- /dev/null +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockEnable.vhd @@ -0,0 +1,125 @@ +------------------------------------------------------------------------------- +-- File : GigEthLvdsClockEnable.vhd +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: SGMII/LVDS Ethernet's clock enabling for 10/100 speeds +------------------------------------------------------------------------------- +-- 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; + +use work.StdRtlPkg.all; + +entity GigEthLvdsClockEnable is + generic ( + TPD_G : time := 1 ns); + port ( + sysClk125 : in sl; + sysRst125 : in sl; + speed_is_10_100 : in sl; + speed_is_100 : in sl; + ethClkEn : out sl); +end entity GigEthLvdsClockEnable; + +architecture rtl of GigEthLvdsClockEnable is + + type RegType is record + ethClkEn : sl; + en100 : sl; + cnt100 : natural range 0 to 9; + en10 : sl; + cnt10 : natural range 0 to 99; + end record RegType; + + constant REG_INIT_C : RegType := ( + ethClkEn => '1', + en100 => '0', + cnt100 => 0, + en10 => '0', + cnt10 => 0); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + +begin + + comb : process (r, speed_is_100, speed_is_10_100, sysRst125) is + variable v : RegType; + begin + -- Latch the current value + v := r; + + -- Reset strobes + v.en100 := '0'; + v.en10 := '0'; + + -- Check for max count + if r.cnt100 = 9 then + -- Reset the counter + v.cnt100 := 0; + -- Set the flag + v.en100 := '1'; + else + -- Increment the counter + v.cnt100 := r.cnt100 + 1; + end if; + + -- Check for max count + if r.cnt10 = 99 then + -- Reset the counter + v.cnt10 := 0; + -- Set the flag + v.en10 := '1'; + else + -- Increment the counter + v.cnt10 := r.cnt10 + 1; + end if; + + -- Check if 10 or 100 speed + if speed_is_10_100 = '1' then + + -- Check if 100 speed + if speed_is_100 = '1' then + v.ethClkEn := r.en100; + + -- Else this is 10 speed + else + v.ethClkEn := r.en10; + end if; + + else + -- 1000 speed (100% duty cycle for clock enable) + v.ethClkEn := '1'; + end if; + + -- Outputs + ethClkEn <= r.ethClkEn; + + -- Reset + if (sysRst125 = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + end process comb; + + seq : process (sysClk125) is + begin + if (rising_edge(sysClk125)) then + r <= rin after TPD_G; + end if; + end process seq; + +end architecture rtl; diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockMux.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockMux.vhd deleted file mode 100644 index 128d5d3a1c..0000000000 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsClockMux.vhd +++ /dev/null @@ -1,54 +0,0 @@ -------------------------------------------------------------------------------- --- File : GigEthLvdsUltraScaleWrapper.vhd --- Company : SLAC National Accelerator Laboratory -------------------------------------------------------------------------------- --- Description: Wrapper for SGMII/LVDS Ethernet -------------------------------------------------------------------------------- --- 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 work.StdRtlPkg.all; - -library unisim; -use unisim.vcomponents.all; - -entity GigEthLvdsClockMux is - port ( - clk125p0 : in sl; - clk12p50 : in sl; - clk1p250 : in sl; - sel12p50 : in sl; - sel1p250 : in sl; - O : out sl - ); -end entity GigEthLvdsClockMux; - -architecture GigEthLvdsClockMuxImpl of GigEthLvdsClockMux is - signal bufCasc : sl; -begin - - U_BUFGMUX_100_1K : BUFGMUX_CTRL - port map ( - I0 => clk125p0, - I1 => clk12p50, - S => sel12p50, - O => bufCasc - ); - - U_BUFGMUX_10 : BUFGMUX_CTRL - port map ( - I0 => bufCasc, - I1 => clk1p250, - S => sel1p250, - O => O - ); -end architecture GigEthLvdsClockMuxImpl; diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScale.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScale.vhd index 9929001154..c9deea6409 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScale.vhd +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScale.vhd @@ -56,8 +56,7 @@ entity GigEthLvdsUltraScale is sysClk312 : in sl; sysClk125 : in sl; sysRst125 : in sl; - ethClk : in sl; - ethRst : in sl; + ethClkEn : in sl; extRst : in sl; phyReady : out sl; sigDet : in sl := '1'; @@ -148,8 +147,9 @@ begin obMacPrimMaster => dmaIbMaster, obMacPrimSlave => dmaIbSlave, -- Ethernet Interface - ethClk => ethClk, - ethRst => ethRst, + ethClkEn => ethClkEn, + ethClk => sysClk125, + ethRst => sysRst125, ethConfig => config.macConfig, ethStatus => status.macStatus, phyReady => status.phyReady, diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd index cf3acf77bc..98badb1673 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd @@ -28,19 +28,16 @@ use unisim.vcomponents.all; entity GigEthLvdsUltraScaleWrapper is generic ( TPD_G : time := 1 ns; - NUM_LANE_G : natural range 1 to 4 := 1; + NUM_LANE_G : positive := 1; PAUSE_EN_G : boolean := true; PAUSE_512BITS_G : positive := 8; -- Clocking Configurations USE_REFCLK_G : boolean := false; -- FALSE: sgmiiClkP/N, TRUE: sgmiiRefClk - CLKIN_PERIOD_G : real := 1.6; - DIVCLK_DIVIDE_G : positive := 1; - CLKFBOUT_MULT_F_G : real := 2.0; + CLKFBOUT_MULT_G : positive := 10; -- AXI-Lite Configurations EN_AXI_REG_G : boolean := false; -- AXI Streaming Configurations - AXIS_CONFIG_G : AxiStreamConfigArray(3 downto 0) := (others => AXI_STREAM_CONFIG_INIT_C) - ); + AXIS_CONFIG_G : AxiStreamConfigArray(3 downto 0) := (others => EMAC_AXIS_CONFIG_C)); port ( -- Local Configurations localMac : in Slv48Array(NUM_LANE_G-1 downto 0) := (others => MAC_ADDR_INIT_C); @@ -68,236 +65,136 @@ entity GigEthLvdsUltraScaleWrapper is speed_is_10_100 : in slv(NUM_LANE_G-1 downto 0) := (others => '0'); speed_is_100 : in slv(NUM_LANE_G-1 downto 0) := (others => '1'); -- MGT Clock Port - sgmiiRefClk : in sl := '0'; - sgmiiClkP : in sl := '1'; - sgmiiClkN : in sl := '0'; + sgmiiRefClk : in sl := '0'; -- 125 MHz + sgmiiClkP : in sl := '1'; -- 625 MHz + sgmiiClkN : in sl := '0'; -- 625 MHz -- MGT Ports sgmiiTxP : out slv(NUM_LANE_G-1 downto 0); sgmiiTxN : out slv(NUM_LANE_G-1 downto 0); sgmiiRxP : in slv(NUM_LANE_G-1 downto 0); - sgmiiRxN : in slv(NUM_LANE_G-1 downto 0) - ); + sgmiiRxN : in slv(NUM_LANE_G-1 downto 0)); end GigEthLvdsUltraScaleWrapper; architecture mapping of GigEthLvdsUltraScaleWrapper is - -- reset is asserted for 2*RST_DURATION_C - constant RST_DURATION_C : natural range 0 to ((2**30)-1) := 156250000; + signal sgmiiClk : sl; + signal sgmiiClkBufg : sl; + signal refClk : sl; + signal refRst : sl; + signal locked : sl; + signal clkFb : sl; - constant NUM_CLOCKS_C : natural := 3; + signal CLKOUT0 : sl; + signal CLKOUT1 : sl; - signal sgmiiClk : sl; - signal refClk : sl; - signal refRst : sl := '1'; - signal sysClk12NB : sl; - signal sysClk125 : sl; - signal sysRst125 : sl; - signal sysClk312 : sl; - signal sysRst312 : sl; - signal sysClk625 : sl; - signal sysRst625 : sl; - signal sysClkNB4 : sl; - signal sysClkNB : slv(6 downto 0); - signal sysClkB : slv(6 downto 0); - signal sysRst : slv(6 downto 0); - signal locked : sl; - signal clkFb : sl; - signal extRstSync : sl; - signal refCE : sl := '0'; - signal refRstCnt : natural range 0 to RST_DURATION_C := RST_DURATION_C; + signal sysClk625 : sl; + signal sysClk312 : sl; + signal sysClk125 : sl; + signal sysRst125 : sl; begin phyClk <= sysClk125; phyRst <= sysRst125; + mmcmLocked <= locked; + ----------------------------- -- Select the Reference Clock ----------------------------- IBUFGDS_SGMII : IBUFGDS - generic map ( - DIFF_TERM => false, - IBUF_LOW_PWR => false - ) port map ( I => sgmiiClkP, IB => sgmiiClkN, - O => sgmiiClk - ); - - refClk <= sgmiiClk when(USE_REFCLK_G = false) else sgmiiRefClk; + O => sgmiiClk); - ----------------- - -- Power Up Reset - -- Timing is a bit tight for the PwrUpRst entity. - -- Use a variant that counts at a sub-harmonic - -- This must be accompanied by an XDC which relaxes - -- timing by means of a multicyle path. - ----------------- - U_RstSync : entity work.RstSync + U_Bufg_sgmiiClk : BUFGCE_DIV generic map ( - TPD_G => TPD_G, - IN_POLARITY_G => '1', - OUT_POLARITY_G => '1' - ) + BUFGCE_DIVIDE => 5) port map ( - clk => refClk, - asyncRst => extRst, - syncRst => extRstSync - ); + I => sgmiiClk, -- 625 MHz (CLKIN_PERIOD_G) + CE => '1', + CLR => '0', + O => sgmiiClkBufg); -- 125 MHz (CLKIN_PERIOD_G*5) - -- don't reset refCE in order to reduce possible - -- timing problems. This leads to uncertainty of - -- 1 clock in the final delay which shouldn't be - -- an issue. - process (refClk) - begin - if (rising_edge(refClk)) then - refCE <= not refCE; - end if; - end process; + refClk <= sgmiiClkBufg when(USE_REFCLK_G = false) else sgmiiRefClk; -- 125 MHz - process (refClk) - begin - if (rising_edge(refClk)) then - if (extRstSync = '1') then - refRst <= '1' after TPD_G; - refRstCnt <= 0 after TPD_G; - else - if (refCE = '1') then - if (refRstCnt = RST_DURATION_C) then - refRst <= '0' after TPD_G; - else - refRstCnt <= refRstCnt + 1 after TPD_G; - end if; - end if; - end if; - end if; - end process; + U_PwrUpRst : entity work.PwrUpRst + generic map( + TPD_G => TPD_G) + port map ( + arst => extRst, + clk => refClk, + rstOut => refRst); ---------------- -- Clock Manager ---------------- - - -- Generate clocks from the reference - -- 625, 312 and 125 MHz for the PCS/PMA. - -- 125MHz also is output as a general 'system clock'. - -- - -- We also generate 12.5MHz and 1.25 MHz (the latter by - -- cascading dividers 4+6) for different ethernet speeds. - -- The Ethernet MAC is run at 125, 12.5 or 1.25 depending - -- on the speed the (external) PHY has negotiated. - -- In case this PHY indeed does support different speeds - -- then additional (external) logic must be able to - -- retrieve the actual speed from the PHY and set the - -- 'speed_is_10_100/speed_is_100' signals so that we - -- can run the MAC at the matching clock... - - -- since we don't care about a skew between the external - -- reference and what we generate here we can omit - -- the BUFG in the feedback chain. - U_MMCM : MMCME3_BASE + U_PLL : PLLE3_BASE generic map( - CLKIN1_PERIOD => CLKIN_PERIOD_G, - DIVCLK_DIVIDE => DIVCLK_DIVIDE_G, - CLKFBOUT_MULT_F => CLKFBOUT_MULT_F_G, -- 1.25GHz - CLKOUT0_DIVIDE_F => 10.0, -- 125 MHz - CLKOUT1_DIVIDE => 4, -- 312.5 MHz - CLKOUT2_DIVIDE => 2, -- 625 MHz - CLKOUT3_DIVIDE => 100, -- 12.5 MHz - CLKOUT4_DIVIDE => 125) -- 10 MHz + CLKIN_PERIOD => 8.0, + DIVCLK_DIVIDE => 1, + CLKFBOUT_MULT => CLKFBOUT_MULT_G, -- 1.25GHz + CLKOUT0_DIVIDE => 2, -- 625 MHz + CLKOUT1_DIVIDE => 10) -- 125 MHz port map ( - CLKIN1 => refClk, + CLKIN => refClk, -- 125 MHz RST => refRst, + PWRDWN => '0', + CLKOUTPHYEN => '0', CLKFBIN => clkFb, CLKFBOUT => clkFb, - CLKOUT0 => sysClkNB(0), - CLKOUT1 => sysClkNB(1), - CLKOUT2 => sysClkNB(2), - CLKOUT3 => sysClkNB(3), - CLKOUT4 => sysClkNB4, - CLKOUT5 => open, - CLKOUT6 => open, - LOCKED => locked, - PWRDWN => '0'); + CLKOUT0 => CLKOUT0, + CLKOUT1 => CLKOUT1, + LOCKED => locked); - U_Bufg_1_25MHz : BUFGCE_DIV + U_sysClk125 : BUFG + port map ( + I => CLKOUT1, + O => sysClk125); + + U_sysRst125 : entity work.RstSync generic map ( - BUFGCE_DIVIDE => 8) + TPD_G => TPD_G, + IN_POLARITY_G => '0') port map ( - I => sysClkNB4, -- 10 MHz + clk => sysClk125, + asyncRst => locked, + syncRst => sysRst125); + + ------------------------------------------------------------------------------------------------------ + -- 312.5 MHz is the ISERDESE3/OSERDESE3's CLKDIV port + -- Refer to "Figure 3-49: Sub-Optimal to Optimal Clocking Topologies for OSERDESE3" in UG949 (v2018.2) + ------------------------------------------------------------------------------------------------------ + U_sysClk312 : BUFGCE_DIV + generic map ( + BUFGCE_DIVIDE => 2) + port map ( + I => CLKOUT0, -- 625 MHz (CLKIN_PERIOD_G) CE => '1', CLR => '0', - O => sysClkNB(4)); -- 1.25 MHz = 10MHz / 8 - - GEN_BUFG : for i in 0 to NUM_CLOCKS_C - 1 generate - U_BUFG_125 : BUFG - port map ( - I => sysClkNB(i), - O => sysClkB(i)); - - U_RESET : entity work.RstSync - generic map ( - TPD_G => TPD_G, - IN_POLARITY_G => '0') - port map ( - clk => sysClkB(i), - asyncRst => locked, - syncRst => sysRst(i)); - end generate; + O => sysClk312); -- 312.5 MHz (CLKIN_PERIOD_G*2) - sysClk125 <= sysClkB(0); - sysRst125 <= sysRst (0); - sysClk312 <= sysClkB(1); - sysRst312 <= sysRst (1); - sysClk625 <= sysClkB(2); - sysRst625 <= sysRst (2); - - mmcmLocked <= locked; + U_sysClk625 : BUFG + port map ( + I => CLKOUT0, + O => sysClk625); -------------- - -- Ethernet 'lanes' (in case multiple ethernets can share a common clock -- however, due to tight timing + -- Ethernet 'lanes' (in case multiple Ethernets can share a common clock -- however, due to tight timing -- they should probably all fit into the same clock region) -------------- GEN_LANE : for i in 0 to NUM_LANE_G-1 generate - signal ethClk : sl; - signal ethRst : sl; - signal speed_is_10 : sl; + signal ethClkEn : sl; begin - speed_is_10 <= speed_is_10_100(i) and not speed_is_100(i); - - -- clock mux to select the MAC core clock according to the - -- desired speed. - -- Note that an appropriate XDC is required (declaring physically - -- exclusive clock groups) for correct timing of such a mux. - - -- Since the cascaded divider has a higher delay we route it - -- through a single buffer only (have not found any spec that - -- says how much phase shift the cascading actually introduces) - -- hoping to balance things a bit. - - U_BUFGMUX_CASC : entity work.GigEthLvdsClockMux - port map ( - clk125p0 => sysClkNB(0), - clk12p50 => sysClkNB(3), - clk1p250 => sysClkNB(4), - sel12p50 => speed_is_10_100(i), - sel1p250 => speed_is_10, - O => ethClk - ); - - -- Generate reset synchronous to the currently selected clock - U_RESET : entity work.RstSync - generic map ( - TPD_G => TPD_G, - IN_POLARITY_G => '0' - ) + U_ethClkEn : entity work.GigEthLvdsClockEnable port map ( - clk => ethClk, - asyncRst => locked, - syncRst => ethRst - ); + sysClk125 => sysClk125, + sysRst125 => sysRst125, + speed_is_10_100 => speed_is_10_100(i), + speed_is_100 => speed_is_100(i), + ethClkEn => ethClkEn); U_GigEthLvdsUltraScale : entity work.GigEthLvdsUltraScale generic map ( @@ -307,8 +204,7 @@ begin -- AXI-Lite Configurations EN_AXI_REG_G => EN_AXI_REG_G, -- AXI Streaming Configurations - AXIS_CONFIG_G => AXIS_CONFIG_G(i) - ) + AXIS_CONFIG_G => AXIS_CONFIG_G(i)) port map ( -- Local Configurations localMac => localMac(i), @@ -327,8 +223,7 @@ begin axiLiteWriteMaster => axiLiteWriteMasters(i), axiLiteWriteSlave => axiLiteWriteSlaves(i), -- PHY + MAC signals - ethClk => ethClk, - ethRst => ethRst, + ethClkEn => ethClkEn, sysClk625 => sysClk625, sysClk312 => sysClk312, sysClk125 => sysClk125, @@ -343,8 +238,7 @@ begin sgmiiTxP => sgmiiTxP(i), sgmiiTxN => sgmiiTxN(i), sgmiiRxP => sgmiiRxP(i), - sgmiiRxN => sgmiiRxN(i) - ); + sgmiiRxN => sgmiiRxN(i)); end generate GEN_LANE; diff --git a/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl b/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl index 7eedd42379..0b3e14aebc 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl +++ b/ethernet/GigEthCore/lvdsUltraScale/ruckus.tcl @@ -2,18 +2,3 @@ source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl loadSource -dir "$::DIR_PATH/rtl" - -if { [info exists ::env(INCLUDE_ETH_SGMII_LVDS)] != 1 || $::env(INCLUDE_ETH_SGMII_LVDS) == 0 } { - set useEthSgmiiLvds 0 -} else { - - - loadConstraints -path "$::DIR_PATH/xdc/GigEthLvdsClockMux.xdc" - set_property SCOPED_TO_REF GigEthLvdsClockMux [get_files "$::DIR_PATH/xdc/GigEthLvdsClockMux.xdc"] - set_property PROCESSING_ORDER LATE [get_files "$::DIR_PATH/xdc/GigEthLvdsClockMux.xdc"] - - loadConstraints -path "$::DIR_PATH/xdc/GigEthLvdsUltraScaleWrapper.xdc" - set_property SCOPED_TO_REF GigEthLvdsUltraScaleWrapper [get_files "$::DIR_PATH/xdc/GigEthLvdsUltraScaleWrapper.xdc"] - set_property PROCESSING_ORDER LATE [get_files "$::DIR_PATH/xdc/GigEthLvdsUltraScaleWrapper.xdc"] - -} diff --git a/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsClockMux.xdc b/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsClockMux.xdc deleted file mode 100644 index b1ae9cb698..0000000000 --- a/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsClockMux.xdc +++ /dev/null @@ -1,20 +0,0 @@ -##----------------------------------------------------------------------------- -## File : GigEthLvdsClockMux.xdc -## Company : SLAC National Accelerator Laboratory -##----------------------------------------------------------------------------- -## Description: Wrapper for SGMII/LVDS Ethernet -##----------------------------------------------------------------------------- -## 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. -##----------------------------------------------------------------------------- - -set c0 [create_generated_clock -divide_by 1 -add -name [get_property NAME [get_pins {U_BUFGMUX_100_1K/I0}]] -master_clock [get_clocks -of [get_ports clk125p0]] -source [get_pins {U_BUFGMUX_100_1K/I0}] [get_pins {U_BUFGMUX_10/O}]] -set c1 [create_generated_clock -divide_by 1 -add -name [get_property NAME [get_pins {U_BUFGMUX_100_1K/I1}]] -master_clock [get_clocks -of [get_ports clk12p50]] -source [get_pins {U_BUFGMUX_100_1K/I1}] [get_pins {U_BUFGMUX_10/O}]] -set c2 [create_generated_clock -divide_by 1 -add -name [get_property NAME [get_pins {U_BUFGMUX_10/I1}]] -master_clock [get_clocks -of [get_ports clk1p250]] -source [get_pins {U_BUFGMUX_10/I1}] [get_pins {U_BUFGMUX_10/O}]] - -set_clock_groups -physically_exclusive -group [get_clocks $c0] -group [get_clocks $c1] -group [get_clocks $c2] diff --git a/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsUltraScaleWrapper.xdc b/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsUltraScaleWrapper.xdc deleted file mode 100644 index 71458b981f..0000000000 --- a/ethernet/GigEthCore/lvdsUltraScale/xdc/GigEthLvdsUltraScaleWrapper.xdc +++ /dev/null @@ -1,22 +0,0 @@ -##----------------------------------------------------------------------------- -## File : GigEthLvdsUltraScaleWrapper.xdc -## Company : SLAC National Accelerator Laboratory -##----------------------------------------------------------------------------- -## Description: Wrapper for SGMII/LVDS Ethernet -##----------------------------------------------------------------------------- -## 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. -##----------------------------------------------------------------------------- - -# Relax timing for the refRstCnt counter (clocked at 625MHz but it has a CE at half the rate) -set_multicycle_path -through [get_pins -of_objects [get_cells {refRstCnt_reg*}] -filter {REF_PIN_NAME==Q}] -setup -start 2 -set_multicycle_path -through [get_pins -of_objects [get_cells {refRstCnt_reg*}] -filter {REF_PIN_NAME==Q}] -hold -start 1 -set_multicycle_path -through [get_pins -of_objects [get_cells {refRst_reg*}] -filter {REF_PIN_NAME==Q}] -setup -start 2 -set_multicycle_path -through [get_pins -of_objects [get_cells {refRst_reg*}] -filter {REF_PIN_NAME==Q}] -hold -start 1 - - From ea09ad2d14adfcb853e4c7126b1543b71f11014d Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 9 Apr 2019 16:09:32 -0700 Subject: [PATCH 82/92] updating to max clk625/clk312 deskewing work for both ultrascale and ultrascale+ designs --- .../Sgmii88E1111LvdsUltraScale.vhd | 7 +- .../rtl/GigEthLvdsUltraScaleWrapper.vhd | 111 ++++++++++-------- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 7545df2023..6a87b4ee5b 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -26,6 +26,7 @@ entity Sgmii88E1111LvdsUltraScale is generic ( TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; + CLKOUT1_PHASE_G : real := 90.0; PHY_G : natural range 0 to 31 := 7; AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( @@ -180,9 +181,9 @@ begin U_1GigE : entity work.GigEthLvdsUltraScaleWrapper generic map ( - TPD_G => TPD_G, - NUM_LANE_G => 1, - AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) + TPD_G => TPD_G, + CLKOUT1_PHASE_G => CLKOUT1_PHASE_G, + AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) port map ( -- Local Configurations localMac(0) => localMac, diff --git a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd index 98badb1673..8bcc64f26d 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd +++ b/ethernet/GigEthCore/lvdsUltraScale/rtl/GigEthLvdsUltraScaleWrapper.vhd @@ -27,17 +27,18 @@ use unisim.vcomponents.all; entity GigEthLvdsUltraScaleWrapper is generic ( - TPD_G : time := 1 ns; - NUM_LANE_G : positive := 1; - PAUSE_EN_G : boolean := true; - PAUSE_512BITS_G : positive := 8; + TPD_G : time := 1 ns; + NUM_LANE_G : positive := 1; + PAUSE_EN_G : boolean := true; + PAUSE_512BITS_G : positive := 8; -- Clocking Configurations - USE_REFCLK_G : boolean := false; -- FALSE: sgmiiClkP/N, TRUE: sgmiiRefClk - CLKFBOUT_MULT_G : positive := 10; + USE_REFCLK_G : boolean := false; -- FALSE: sgmiiClkP/N, TRUE: sgmiiRefClk + CLKFBOUT_MULT_G : positive := 10; + CLKOUT1_PHASE_G : real := 90.0; -- AXI-Lite Configurations - EN_AXI_REG_G : boolean := false; + EN_AXI_REG_G : boolean := false; -- AXI Streaming Configurations - AXIS_CONFIG_G : AxiStreamConfigArray(3 downto 0) := (others => EMAC_AXIS_CONFIG_C)); + AXIS_CONFIG_G : AxiStreamConfigArray(3 downto 0) := (others => EMAC_AXIS_CONFIG_C)); port ( -- Local Configurations localMac : in Slv48Array(NUM_LANE_G-1 downto 0) := (others => MAC_ADDR_INIT_C); @@ -65,9 +66,9 @@ entity GigEthLvdsUltraScaleWrapper is speed_is_10_100 : in slv(NUM_LANE_G-1 downto 0) := (others => '0'); speed_is_100 : in slv(NUM_LANE_G-1 downto 0) := (others => '1'); -- MGT Clock Port - sgmiiRefClk : in sl := '0'; -- 125 MHz - sgmiiClkP : in sl := '1'; -- 625 MHz - sgmiiClkN : in sl := '0'; -- 625 MHz + sgmiiRefClk : in sl := '0'; -- 125 MHz + sgmiiClkP : in sl := '1'; -- 625 MHz + sgmiiClkN : in sl := '0'; -- 625 MHz -- MGT Ports sgmiiTxP : out slv(NUM_LANE_G-1 downto 0); sgmiiTxN : out slv(NUM_LANE_G-1 downto 0); @@ -84,8 +85,8 @@ architecture mapping of GigEthLvdsUltraScaleWrapper is signal locked : sl; signal clkFb : sl; - signal CLKOUT0 : sl; - signal CLKOUT1 : sl; + signal CLKOUT0 : sl; + signal CLKOUT1 : sl; signal sysClk625 : sl; signal sysClk312 : sl; @@ -117,7 +118,7 @@ begin CLR => '0', O => sgmiiClkBufg); -- 125 MHz (CLKIN_PERIOD_G*5) - refClk <= sgmiiClkBufg when(USE_REFCLK_G = false) else sgmiiRefClk; -- 125 MHz + refClk <= sgmiiClkBufg when(USE_REFCLK_G = false) else sgmiiRefClk; -- 125 MHz U_PwrUpRst : entity work.PwrUpRst generic map( @@ -130,28 +131,44 @@ begin ---------------- -- Clock Manager ---------------- - U_PLL : PLLE3_BASE + U_PLL : PLLE3_ADV generic map( - CLKIN_PERIOD => 8.0, - DIVCLK_DIVIDE => 1, - CLKFBOUT_MULT => CLKFBOUT_MULT_G, -- 1.25GHz - CLKOUT0_DIVIDE => 2, -- 625 MHz - CLKOUT1_DIVIDE => 10) -- 125 MHz + CLKOUTPHY_MODE => "VCO", + COMPENSATION => "INTERNAL", + STARTUP_WAIT => "FALSE", + CLKIN_PERIOD => 8.0, + DIVCLK_DIVIDE => 1, + CLKFBOUT_MULT => CLKFBOUT_MULT_G, -- 1.25GHz + CLKOUT0_DIVIDE => 2, -- 625 MHz + CLKOUT1_DIVIDE => 4, -- 312.5 MHz + CLKOUT0_PHASE => 0.0, + CLKOUT1_PHASE => CLKOUT1_PHASE_G) -- Deskew the clk0/clk1 port map ( - CLKIN => refClk, -- 125 MHz - RST => refRst, - PWRDWN => '0', - CLKOUTPHYEN => '0', - CLKFBIN => clkFb, - CLKFBOUT => clkFb, - CLKOUT0 => CLKOUT0, - CLKOUT1 => CLKOUT1, - LOCKED => locked); - - U_sysClk125 : BUFG + DCLK => '0', + DRDY => open, + DEN => '0', + DWE => '0', + DADDR => (others => '0'), + DI => (others => '0'), + DO => open, + PWRDWN => '0', + CLKOUTPHYEN => '0', + CLKIN => refClk, -- 125 MHz + RST => refRst, + CLKFBIN => clkFb, + CLKFBOUT => clkFb, + CLKOUT0 => CLKOUT0, + CLKOUT1 => CLKOUT1, + LOCKED => locked); + + U_sysClk125 : BUFGCE_DIV + generic map ( + BUFGCE_DIVIDE => 5) port map ( - I => CLKOUT1, - O => sysClk125); + I => CLKOUT0, + CE => '1', + CLR => '0', + O => sysClk125); U_sysRst125 : entity work.RstSync generic map ( @@ -160,30 +177,26 @@ begin port map ( clk => sysClk125, asyncRst => locked, - syncRst => sysRst125); - - ------------------------------------------------------------------------------------------------------ - -- 312.5 MHz is the ISERDESE3/OSERDESE3's CLKDIV port - -- Refer to "Figure 3-49: Sub-Optimal to Optimal Clocking Topologies for OSERDESE3" in UG949 (v2018.2) - ------------------------------------------------------------------------------------------------------ - U_sysClk312 : BUFGCE_DIV - generic map ( - BUFGCE_DIVIDE => 2) - port map ( - I => CLKOUT0, -- 625 MHz (CLKIN_PERIOD_G) - CE => '1', - CLR => '0', - O => sysClk312); -- 312.5 MHz (CLKIN_PERIOD_G*2) + syncRst => sysRst125); + ---------------------------------------------------------- + -- Refer to "Fig: Fabric Clocking With MMCM clock outputs" + -- https://www.xilinx.com/support/answers/67885.html + ---------------------------------------------------------- U_sysClk625 : BUFG port map ( I => CLKOUT0, O => sysClk625); - -------------- + U_sysClk312 : BUFG + port map ( + I => CLKOUT1, + O => sysClk312); + + -------------------------------------------------------------------------------------------------------- -- Ethernet 'lanes' (in case multiple Ethernets can share a common clock -- however, due to tight timing -- they should probably all fit into the same clock region) - -------------- + -------------------------------------------------------------------------------------------------------- GEN_LANE : for i in 0 to NUM_LANE_G-1 generate signal ethClkEn : sl; begin From e6181fcd471cac085de27eeba783ee3deef12b58 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Apr 2019 08:55:14 -0700 Subject: [PATCH 83/92] adding ti/Ds32Ev400.py --- python/surf/devices/ti/_Ds32Ev400.py | 222 +++++++++++++++++++++++++++ python/surf/devices/ti/__init__.py | 1 + 2 files changed, 223 insertions(+) create mode 100644 python/surf/devices/ti/_Ds32Ev400.py diff --git a/python/surf/devices/ti/_Ds32Ev400.py b/python/surf/devices/ti/_Ds32Ev400.py new file mode 100644 index 0000000000..433fb147ea --- /dev/null +++ b/python/surf/devices/ti/_Ds32Ev400.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +#----------------------------------------------------------------------------- +# This file is part of the rogue software platform. 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 the rogue software platform, including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class Ds32Ev400(pr.Device): + def __init__( self, + name = 'Ds32Ev400', + description = 'Ds32Ev400 Module', + **kwargs): + + super().__init__(name=name,description=description,**kwargs) + + self.add(pr.RemoteVariable( + name = 'SmBusEnable', + description = '0: Disabled, 1: Enabled', + offset = (0x07 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'SD', + description = 'Signal Detect', + offset = (0x00 << 2), + bitSize = 4, + bitOffset = 0, + mode = 'RO', + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = 'ID', + description = 'ID Revision', + offset = (0x00 << 2), + bitSize = 4, + bitOffset = 4, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'En[0]', + description = 'enable controlled by SMBus', + offset = (0x01 << 2), + bitSize = 1, + bitOffset = 3, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'En[1]', + description = 'enable controlled by SMBus', + offset = (0x01 << 2), + bitSize = 1, + bitOffset = 7, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'En[2]', + description = 'enable controlled by SMBus', + offset = (0x02 << 2), + bitSize = 1, + bitOffset = 3, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'En[3]', + description = 'enable controlled by SMBus', + offset = (0x02 << 2), + bitSize = 1, + bitOffset = 7, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'Boost[0]', + description = 'equalizer boost setting controlled by SMBus', + offset = (0x01 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'Boost[1]', + description = 'equalizer boost setting controlled by SMBus', + offset = (0x01 << 2), + bitSize = 3, + bitOffset = 4, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'Boost[2]', + description = 'equalizer boost setting controlled by SMBus', + offset = (0x02 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'Boost[3]', + description = 'equalizer boost setting controlled by SMBus', + offset = (0x02 << 2), + bitSize = 3, + bitOffset = 4, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OeL[0]', + description = '0: enabled, 1: disabled', + offset = (0x03 << 2), + bitSize = 1, + bitOffset = 3, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OeL[1]', + description = '0: enabled, 1: disabled', + offset = (0x03 << 2), + bitSize = 1, + bitOffset = 7, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OeL[2]', + description = '0: enabled, 1: disabled', + offset = (0x04 << 2), + bitSize = 1, + bitOffset = 3, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OeL[3]', + description = '0: enabled, 1: disabled', + offset = (0x04 << 2), + bitSize = 1, + bitOffset = 7, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'BoostControl[0]', + description = 'BST_N setting controlled by SMBus', + offset = (0x03 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'BoostControl[1]', + description = 'BST_N setting controlled by SMBus', + offset = (0x03 << 2), + bitSize = 3, + bitOffset = 4, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'BoostControl[2]', + description = 'BST_N setting controlled by SMBus', + offset = (0x04 << 2), + bitSize = 3, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'BoostControl[3]', + description = 'BST_N setting controlled by SMBus', + offset = (0x04 << 2), + bitSize = 3, + bitOffset = 4, + mode = 'RW', + )) + + for i in range(4): + + self.add(pr.RemoteVariable( + name = f'SdOnThreshold[{i}]', + description = 'Signal Detect ON threshold', + offset = (0x05 << 2), + bitSize = 2, + bitOffset = 2*i, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = f'SdOffThreshold[{i}]', + description = 'Signal Detect OFF threshold', + offset = (0x06 << 2), + bitSize = 2, + bitOffset = 2*i, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'OutputLevel', + description = 'Sets the output diff. swing', + offset = (0x08 << 2), + bitSize = 2, + bitOffset = 2, + mode = 'RW', + )) + \ No newline at end of file diff --git a/python/surf/devices/ti/__init__.py b/python/surf/devices/ti/__init__.py index 123a1c5866..41de0e5c44 100644 --- a/python/surf/devices/ti/__init__.py +++ b/python/surf/devices/ti/__init__.py @@ -16,6 +16,7 @@ from surf.devices.ti._Ads54J60Channel import * from surf.devices.ti._AxiCdcm6208 import * from surf.devices.ti._Dac38J84 import * +from surf.devices.ti._Ds32Ev400 import * from surf.devices.ti._Lmk04828 import * from surf.devices.ti._Lmk61e2 import * from surf.devices.ti._Pca9535 import * From 436f4cf378db858e095fa3f350cfc6771eaa38f3 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Apr 2019 08:55:50 -0700 Subject: [PATCH 84/92] bug fixes to silabs/Si5345 --- python/surf/devices/silabs/_Si5345.py | 84 +++++++++++++++++++-------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/python/surf/devices/silabs/_Si5345.py b/python/surf/devices/silabs/_Si5345.py index 1216f8b53d..e4ecb27159 100644 --- a/python/surf/devices/silabs/_Si5345.py +++ b/python/surf/devices/silabs/_Si5345.py @@ -80,15 +80,15 @@ def LoadCsvFile(arg): ############################## # Devices ############################## - self.add(Si5345Page0(offset=0x000,simpleDisplay=simpleDisplay,expand=False)) - self.add(Si5345Page1(offset=0x100,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page2(offset=0x200,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page3(offset=0x300,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page4(offset=0x400,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page5(offset=0x500,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345Page9(offset=0x900,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345PageA(offset=0xA00,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) - self.add(Si5345PageB(offset=0xB00,simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page0(offset=(0x000<<2),simpleDisplay=simpleDisplay,expand=False)) + self.add(Si5345Page1(offset=(0x100<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page2(offset=(0x200<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page3(offset=(0x300<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page4(offset=(0x400<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page5(offset=(0x500<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345Page9(offset=(0x900<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345PageA(offset=(0xA00<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) + self.add(Si5345PageB(offset=(0xB00<<2),simpleDisplay=simpleDisplay,expand=False,hidden=advanceUser)) class Si5345Page0(pr.Device): def __init__(self, @@ -124,7 +124,7 @@ def __init__(self, name = 'GRADE', description = 'One ASCII character indicating the device speed/synthesis mode.', offset = (0x04 << 2), - bitSize = 8, + bitSize = 2, mode = 'RO', enum = { 0x0: 'A', @@ -139,7 +139,7 @@ def __init__(self, name = 'DEVICE_REV', description = 'One ASCII character indicating the device revision level.', offset = (0x05 << 2), - bitSize = 8, + bitSize = 2, mode = 'RO', enum = { 0x0: 'A', @@ -753,6 +753,9 @@ def __init__(self, 0x2: 'CLKIN2', 0x3: 'CLKIN3', 0x4: 'XAXB', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -1039,6 +1042,11 @@ def __init__(self, 0x8: '1000 ppm', 0x9: '3000 ppm', 0xA: '10000 ppm', + 0xB: 'UNDEFINED_0xB', + 0xC: 'UNDEFINED_0xC', + 0xD: 'UNDEFINED_0xD', + 0xE: 'UNDEFINED_0xE', + 0xF: 'UNDEFINED_0xF', }, overlapEn = True, )) @@ -1062,6 +1070,11 @@ def __init__(self, 0x8: '1000 ppm', 0x9: '3000 ppm', 0xA: '10000 ppm', + 0xB: 'UNDEFINED_0xB', + 0xC: 'UNDEFINED_0xC', + 0xD: 'UNDEFINED_0xD', + 0xE: 'UNDEFINED_0xE', + 0xF: 'UNDEFINED_0xF', }, overlapEn = True, )) @@ -1095,12 +1108,12 @@ def __init__(self, bitSize = 8, bitOffset = 0, mode = 'RO', - enum = { - 0x00: 'zero', - 0x03: 'one', - 0x0F: 'two', - 0x3F: 'three', - }, + # enum = { + # 0x00: 'zero', + # 0x03: 'one', + # 0x0F: 'two', + # 0x3F: 'three', + # }, overlapEn = True, )) @@ -1360,16 +1373,18 @@ def __init__(self, name = f'OUT_FORMAT[{i}]', description = 'OUT_FORMAT', offset = ( ((0x09+(5*i)) << 2) if (i!=9) else ((0x09+(5*i)+5) << 2) ), - bitSize = 2, + bitSize = 3, bitOffset = 0, mode = 'RW', enum = { 0x0: 'Undefined', 0x1: 'swing mode (normal swing) differential', 0x2: 'swing mode (high swing) differential', + 0x3: 'UNDEFINED_0x3', 0x4: 'LVCMOS single ended', 0x5: 'LVCMOS (+pin only)', 0x6: 'LVCMOS (pin only)', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -1395,6 +1410,8 @@ def __init__(self, enum = { 0x0: 'Disable low', 0x1: 'Disable high', + 0x2: 'UNDEFINED_0x2', + 0x3: 'UNDEFINED_0x3', }, overlapEn = True, )) @@ -1410,6 +1427,7 @@ def __init__(self, 0x0: 'CMOS1', 0x1: 'CMOS2', 0x2: 'CMOS3', + 0x3: 'UNDEFINED_0x3', }, overlapEn = True, )) @@ -1447,6 +1465,9 @@ def __init__(self, 0x2: 'N2', 0x3: 'N3', 0x4: 'N4', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -1473,6 +1494,7 @@ def __init__(self, 0x0: '3.3 V', 0x1: '1.8 V', 0x2: '2.5 V', + 0x3: 'UNDEFINED_0x3', }, overlapEn = True, )) @@ -2294,6 +2316,7 @@ def __init__(self, 0x0: 'IN0', 0x1: 'IN1', 0x2: 'IN2', + 0x3: 'UNDEFINED_0x3', }, overlapEn = True, )) @@ -2609,6 +2632,7 @@ def __init__(self, 0x0: 'manual', 0x1: 'automatic_non-revertive', 0x2: 'automatic_revertive', + 0x3: 'UNDEFINED_0x3', }, overlapEn = True, )) @@ -2657,6 +2681,9 @@ def __init__(self, 0x2: 'priority 2', 0x3: 'priority 3', 0x4: 'priority 4', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -2674,6 +2701,9 @@ def __init__(self, 0x2: 'priority 2', 0x3: 'priority 3', 0x4: 'priority 4', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -2691,6 +2721,9 @@ def __init__(self, 0x2: 'priority 2', 0x3: 'priority 3', 0x4: 'priority 4', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -2708,6 +2741,9 @@ def __init__(self, 0x2: 'priority 2', 0x3: 'priority 3', 0x4: 'priority 4', + 0x5: 'UNDEFINED_0x5', + 0x6: 'UNDEFINED_0x6', + 0x7: 'UNDEFINED_0x7', }, overlapEn = True, )) @@ -2719,9 +2755,9 @@ def __init__(self, bitSize = 2, bitOffset = 0, mode = 'WO', - value = 0x2, - hidden = True, - verify = False, + value = 0x2, + hidden = True, + verify = False, overlapEn = True, )) @@ -2732,9 +2768,9 @@ def __init__(self, bitSize = 2, bitOffset = 2, mode = 'WO', - value = 0x0, - hidden = True, - verify = False, + value = 0x0, + hidden = True, + verify = False, overlapEn = True, )) From 6a0f972e9c72cfad3033dcb7920c87eae91a1af4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Apr 2019 09:23:23 -0700 Subject: [PATCH 85/92] Bug fixes for UltraScale/ClinkDataClk.vhd --- protocols/clink/UltraScale/ClinkDataClk.vhd | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/protocols/clink/UltraScale/ClinkDataClk.vhd b/protocols/clink/UltraScale/ClinkDataClk.vhd index c379aefeee..93f39c2704 100644 --- a/protocols/clink/UltraScale/ClinkDataClk.vhd +++ b/protocols/clink/UltraScale/ClinkDataClk.vhd @@ -89,11 +89,11 @@ begin drpDi => drpDi, drpDo => drpDo); - U_Mmcm : MMCME2_ADV + U_Mmcm : MMCME3_ADV generic map ( BANDWIDTH => "OPTIMIZED", - CLKOUT4_CASCADE => false, - STARTUP_WAIT => false, + CLKOUT4_CASCADE => "FALSE", + STARTUP_WAIT => "FALSE", -- CLKIN1_PERIOD => 40.0, -- 25 MHz -- DIVCLK_DIVIDE => 1, -- CLKFBOUT_MULT_F => 42.0, -- VCO = 1050MHz @@ -128,28 +128,22 @@ begin U_RegGen : if REG_BUFF_EN_G generate - U_BufIn : BUFR + U_BufIn : BUFG port map ( - CE => '0', - CLR => '0', I => clkIn, O => clkInLoc); - U_BufFb : BUFR + U_BufFb : BUFG port map ( - CE => '0', - CLR => '0', I => clkFbOut, O => clkFbIn); - U_BufOut : BUFR + U_BufOut : BUFG port map ( - CE => '0', - CLR => '0', I => clkOutMmcm(0), O => clkOutLoc(0)); - U_BufIo : BUFIO + U_BufIo : BUFG port map ( I => clkOutMmcm(1), O => clkOutLoc(1)); From 7ee1222fac333deaf74f23865e38dcb039180137 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Apr 2019 09:25:30 -0700 Subject: [PATCH 86/92] Update ClinkDataShift.vhd --- protocols/clink/UltraScale/ClinkDataShift.vhd | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd index 4bb08ab6ff..744ccd3d8c 100644 --- a/protocols/clink/UltraScale/ClinkDataShift.vhd +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -75,11 +75,14 @@ architecture structure of ClinkDataShift is signal serdes : Slv8Array(4 downto 0); signal dataShift : Slv7Array(4 downto 0); signal clkReset : sl; + signal dlyRstL : sl; attribute IODELAY_GROUP : string; begin + dlyRstL <= not(dlyRst); + U_clkInFreq : entity work.SyncClockFreq generic map ( TPD_G => TPD_G, @@ -204,7 +207,7 @@ begin CLK => dlyClk, -- 1-bit input: Clock input CNTVALUEIN => intDelay, -- 9-bit input: Counter value input DATAIN => '0', -- 1-bit input: Data input from the logic - EN_VTC => '1', -- 1-bit input: Keep delay constant over VT + EN_VTC => dlyRstL, -- 1-bit input: Keep delay constant over VT IDATAIN => cblIn(i), -- 1-bit input: Data input from the IOBUF INC => '0', -- 1-bit input: Increment / Decrement tap delay input LOAD => intLd, -- 1-bit input: Load DELAY_VALUE input From 2acd52c174c474eaff49d2ec1e3a076999a9344d Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Apr 2019 10:58:42 -0700 Subject: [PATCH 87/92] Update ClinkDataShift.vhd --- protocols/clink/UltraScale/ClinkDataShift.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/clink/UltraScale/ClinkDataShift.vhd b/protocols/clink/UltraScale/ClinkDataShift.vhd index 744ccd3d8c..aa3b7906d5 100644 --- a/protocols/clink/UltraScale/ClinkDataShift.vhd +++ b/protocols/clink/UltraScale/ClinkDataShift.vhd @@ -188,7 +188,7 @@ begin U_Delay : IDELAYE3 generic map ( CASCADE => "NONE", -- Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE) - DELAY_FORMAT => "TIME", -- Units of the DELAY_VALUE (COUNT, TIME) + DELAY_FORMAT => "COUNT", -- Units of the DELAY_VALUE (COUNT, TIME) DELAY_SRC => "IDATAIN", -- Delay input (DATAIN, IDATAIN) DELAY_TYPE => "VAR_LOAD", -- Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD) DELAY_VALUE => 0, -- Input delay value setting @@ -207,7 +207,7 @@ begin CLK => dlyClk, -- 1-bit input: Clock input CNTVALUEIN => intDelay, -- 9-bit input: Counter value input DATAIN => '0', -- 1-bit input: Data input from the logic - EN_VTC => dlyRstL, -- 1-bit input: Keep delay constant over VT + EN_VTC => '0', -- 1-bit input: Keep delay constant over VT IDATAIN => cblIn(i), -- 1-bit input: Data input from the IOBUF INC => '0', -- 1-bit input: Increment / Decrement tap delay input LOAD => intLd, -- 1-bit input: Load DELAY_VALUE input From 3da995018e4c4ec8776322b7791dd63ec010cc24 Mon Sep 17 00:00:00 2001 From: Leonid Sapozhnikov Date: Thu, 11 Apr 2019 16:07:06 -0700 Subject: [PATCH 88/92] Fixed proper init for address and write data --- protocols/uart/rtl/UartAxiLiteMaster.vhd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocols/uart/rtl/UartAxiLiteMaster.vhd b/protocols/uart/rtl/UartAxiLiteMaster.vhd index 02018fd442..0a4cd552df 100644 --- a/protocols/uart/rtl/UartAxiLiteMaster.vhd +++ b/protocols/uart/rtl/UartAxiLiteMaster.vhd @@ -194,6 +194,7 @@ begin when WAIT_START_S => -- Any characters before 'r' or 'w' are thrown out if (uartRxValid = '1') then + v.axilReq.address := (Others => '0'); if (uartRxData = toSlv(character'pos('w'), 8) or uartRxData = toSlv(character'pos('W'), 8)) then -- Write op @@ -237,6 +238,7 @@ begin if (isSpace(uartRxData)) then v.axilReq.address := r.axilReq.address; if (r.axilReq.rnw = '0') then + v.axilReq.wrData := (Others => '0'); v.state := WR_DATA_S; else v.state := WAIT_EOL_S; From 9c242290fb2357abb22107ce4808b8625419b17d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 11 Apr 2019 16:17:28 -0700 Subject: [PATCH 89/92] Fix formatting --- protocols/uart/rtl/UartAxiLiteMaster.vhd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protocols/uart/rtl/UartAxiLiteMaster.vhd b/protocols/uart/rtl/UartAxiLiteMaster.vhd index 0a4cd552df..62e2f3a6c9 100644 --- a/protocols/uart/rtl/UartAxiLiteMaster.vhd +++ b/protocols/uart/rtl/UartAxiLiteMaster.vhd @@ -194,7 +194,7 @@ begin when WAIT_START_S => -- Any characters before 'r' or 'w' are thrown out if (uartRxValid = '1') then - v.axilReq.address := (Others => '0'); + v.axilReq.address := (others => '0'); if (uartRxData = toSlv(character'pos('w'), 8) or uartRxData = toSlv(character'pos('W'), 8)) then -- Write op @@ -238,8 +238,8 @@ begin if (isSpace(uartRxData)) then v.axilReq.address := r.axilReq.address; if (r.axilReq.rnw = '0') then - v.axilReq.wrData := (Others => '0'); - v.state := WR_DATA_S; + v.axilReq.wrData := (others => '0'); + v.state := WR_DATA_S; else v.state := WAIT_EOL_S; end if; From 86a837c3f26b381775671dda43f766a846d521ff Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 12 Apr 2019 08:52:03 -0700 Subject: [PATCH 90/92] Fix bad disp strings --- python/surf/axi/_AxiStreamScatterGather.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/python/surf/axi/_AxiStreamScatterGather.py b/python/surf/axi/_AxiStreamScatterGather.py index 2d4236d313..b979b3b1cf 100644 --- a/python/surf/axi/_AxiStreamScatterGather.py +++ b/python/surf/axi/_AxiStreamScatterGather.py @@ -10,13 +10,13 @@ def __init__(self, name = 'RxRamWrAddr', mode = 'RO', offset = 0x00, - disp = '{:08x}')) + disp = '{:#08x}')) self.add(pr.RemoteVariable( name = 'RxSofAddr', mode = 'RO', offset = 0x04, - disp = '{:08x}')) + disp = '{:#08x}')) self.add(pr.RemoteVariable( name = 'RxWordCount', @@ -37,14 +37,13 @@ def __init__(self, offset = 0x0C, bitSize = 1, bitOffset = 31, - base = pr.Bool, - disp = '{:08x}')) + base = pr.Bool)) self.add(pr.RemoteVariable( name = 'TxRamRdAddr', mode = 'RO', offset = 0x10, - disp = '{:08x}')) + disp = '{:#08x}')) self.add(pr.RemoteVariable( name = 'TxWordCount', From 5ed58cb8d278c104f1375896b34fe5587b3069e5 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 12 Apr 2019 09:52:13 -0700 Subject: [PATCH 91/92] Fix whitespace --- protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd index 822af3118c..28858f4d72 100755 --- a/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd +++ b/protocols/pgp/pgp2b/core/rtl/Pgp2bPkg.vhd @@ -25,7 +25,7 @@ package Pgp2bPkg is ----------------------------------------------------- -- Constants ----------------------------------------------------- - constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_COMP_C); + constant SSI_PGP2B_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(2, TKEEP_COMP_C); -- 8B10B Characters constant K_COM_C : slv(7 downto 0) := "10111100"; -- K28.5, 0xBC From 0686fa4600f7786f16b9abc8d2d141af5c30bdb7 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Fri, 12 Apr 2019 09:56:30 -0700 Subject: [PATCH 92/92] Revert TKEEP_FIXED behavior --- axi/axi-stream/rtl/AxiStreamFifoV2.vhd | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamFifoV2.vhd b/axi/axi-stream/rtl/AxiStreamFifoV2.vhd index e008f1627f..41d1384199 100644 --- a/axi/axi-stream/rtl/AxiStreamFifoV2.vhd +++ b/axi/axi-stream/rtl/AxiStreamFifoV2.vhd @@ -176,9 +176,8 @@ begin -- Cant use tkeep_fixed on master side when resizing or if not on slave side assert (not (MASTER_AXI_CONFIG_G.TKEEP_MODE_C = TKEEP_FIXED_C and SLAVE_AXI_CONFIG_G.TKEEP_MODE_C /= TKEEP_FIXED_C)) - report "AxiStreamFifoV2: TKEEP_MODE = TKEEP_FIXED on master side if not on slave side. "& - "This is dangerous as odd sized frames will be padded with garbage data." - severity warning; + report "AxiStreamFifoV2: Can't have TKEEP_MODE = TKEEP_FIXED on master side if not on slave side" + severity error; ------------------------- -- Slave Resize