diff --git a/driver/linux/riffa_driver.c b/driver/linux/riffa_driver.c index aeb6f8d..dc4b86b 100644 --- a/driver/linux/riffa_driver.c +++ b/driver/linux/riffa_driver.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include "riffa_driver.h" @@ -156,58 +157,93 @@ unsigned long long __udivdi3(unsigned long long num, unsigned long long den) } #endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,11) -/** - * Used to set ETB and RCB, but not available before 3.7. As it is peppered - * throughout the clean up code, it's just easier to define empty implementations - * here than a bunch of conditionals everywhere else. - */ -#ifndef PCI_EXP_DEVCTL -#define PCI_EXP_DEVCTL 0 -#endif -#ifndef PCI_EXP_DEVCTL_EXT_TAG -#define PCI_EXP_DEVCTL_EXT_TAG 0 -#endif -#ifndef PCI_EXP_DEVCTL_RELAX_EN -#define PCI_EXP_DEVCTL_RELAX_EN 0 -#endif -#ifndef PCI_EXP_DEVCTL2 -#define PCI_EXP_DEVCTL2 0 -#endif + +// These are not defined in the 2.x.y kernels, so just define them +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39) +#define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x100 +#define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x200 +#else +/** + * These are badly named in pre-3.6.11 kernel versions. We COULD do the same + * check as above, however (annoyingly) linux for tegra (based on post-3.6.11) + * picked up the header file from some pre-3.6.11 version, so we'll just make + * our code ugly and handle the check here: + */ #ifndef PCI_EXP_DEVCTL2_IDO_REQ_EN -#define PCI_EXP_DEVCTL2_IDO_REQ_EN 0 +#define PCI_EXP_DEVCTL2_IDO_REQ_EN PCI_EXP_IDO_REQ_EN #endif #ifndef PCI_EXP_DEVCTL2_IDO_CMP_EN -#define PCI_EXP_DEVCTL2_IDO_CMP_EN 0 +#define PCI_EXP_DEVCTL2_IDO_CMP_EN PCI_EXP_IDO_CMP_EN #endif -#ifndef PCI_EXP_DEVCTL -#define PCI_EXP_DEVCTL 0 -#endif -#ifndef PCI_EXP_LNKCTL_RCB -#define PCI_EXP_LNKCTL_RCB 0 #endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,11) +/** + * Code used to set ETB and RCB, but not available before 3.0, or incorrectly + * defined before 3.7. As it is peppered throughout the clean up code, it's just + * easier to copy the declarations (not verbatim) here than a bunch of conditionals + * everywhere else. + */ + int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) { - return 0; + int ret; + + *val = 0; + if (pos & 1) + return -EINVAL; + + ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); + /* + * Reset *val to 0 if pci_read_config_word() fails, it may + * have been written as 0xFFFF if hardware error happens + * during pci_read_config_word(). + */ + if (ret) + *val = 0; + return ret; } int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) { - return 0; + int ret; + + *val = 0; + if (pos & 3) + return -EINVAL; + + ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); + /* + * Reset *val to 0 if pci_read_config_dword() fails, it may + * have been written as 0xFFFFFFFF if hardware error happens + * during pci_read_config_dword(). + */ + if (ret) + *val = 0; + return ret; + } int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) { - return 0; + if (pos & 1) + return -EINVAL; + + return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); } int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) { - return 0; + if (pos & 3) + return -EINVAL; + + return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); } #endif + + + /////////////////////////////////////////////////////// // INTERRUPT HANDLER /////////////////////////////////////////////////////// diff --git a/driver/windows/README.txt b/driver/windows/README.txt index a6aed3a..9bc8daf 100755 --- a/driver/windows/README.txt +++ b/driver/windows/README.txt @@ -4,10 +4,16 @@ To build the Windows driver: version 7600.16385.1). 2) Open a DDK command window environment for Windows 7 (which ever version you're targeting). -3) Move to the directory containing this README.txt and run: build -ceZ +3) Move to the directory containing this README.txt and run build -ceZ 4) The driver should be built and ready in the output directory along with a Windows 7 catalog file and the coinstaller DLLs. - +5) To build the installer you will need to build the driver using the DDK for + each architecture (x86/x64). If you want both setup.exe and setup_dbg.exe + executables, you will run the build command FOUR TIMES before step 6. +6) To build the setup.exe file, run the win7install.bat script from the DDK + unchecked/free command window. To build the setup_dbg.exe file, run the + script from the checked command window. + A few notes: - You will need to sign the driver (riffa.sys) and catalog file (riffa.cat) @@ -15,7 +21,11 @@ A few notes: process will attempt to sign the catalog file with the UCSD certificate. You don't have that, so you won't get a signed driver simply by building. You'll need to get a certificate from a certificate authority that is capable of - cross-certificate kernel driver signing. See this page for more details: + cross-certificate kernel driver signing to authenticate yourself (.pfx), + and the cross-signing certificate from that authority (.crt file available + from link). These should both be added to the windows certificate list and + and copied into the root folder for the windows driver (same location as this + README.txt file). See this page for more details: http://msdn.microsoft.com/en-us/windows/hardware/gg487315.aspx - Debugging on Windows is difficult because there exists no kernel log file. diff --git a/driver/windows/install/install.bat b/driver/windows/install/install.bat index 861cd5b..d8c2a44 100755 --- a/driver/windows/install/install.bat +++ b/driver/windows/install/install.bat @@ -1,4 +1,4 @@ -@echo off +@echo on rmdir /s /q build md build @@ -14,12 +14,21 @@ xcopy /E /H /K /I /Y ..\..\..\c_c++\windows .\build\c_c++ xcopy /E /H /K /I /Y ..\..\..\java .\build\java xcopy /E /H /K /I /Y ..\..\..\python .\build\python xcopy /E /H /K /I /Y ..\..\..\matlab .\build\matlab +echo "%3" if "%3" == "chk" ( - "c:\program files\inno setup 5\iscc.exe" /dDebug="1" /o.\build .\build\win7.iss + md .\build.\tmp_dbg + "c:\program files (x86)\inno setup 5\iscc.exe" /dDebug="1" /o.\build\tmp_dbg .\build\win7.iss + signtool sign /v /ac "..\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll .\build\tmp_dbg\setup.exe + move .\build\tmp_dbg\setup.exe .\setup_dbg.exe + rmdir /s /q .\build\tmp_dbg\ ) else ( - "c:\program files\inno setup 5\iscc.exe" /o.\build .\build\win7.iss + md .\build\tmp + "c:\program files (x86)\inno setup 5\iscc.exe" /o.\build\tmp\ .\build\win7.iss + signtool sign /v /ac "..\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll .\build\tmp\setup.exe + move .\build\tmp\setup.exe .\setup.exe + rmdir /s /q .\build\tmp\ ) -signtool sign /v /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll .\build\setup.exe + diff --git a/driver/windows/install/win7.iss b/driver/windows/install/win7.iss index 8f973e8..9e4f863 100755 --- a/driver/windows/install/win7.iss +++ b/driver/windows/install/win7.iss @@ -13,7 +13,7 @@ [Setup] AppName=RIFFA -AppVersion=2.0 +AppVersion=2.2.1 AppPublisher=University of California, San Diego AppPublisherURL=https://sites.google.com/a/eng.ucsd.edu/matt-jacobsen/riffa AppCopyright=Copyright (C) 2016 The Regents of the University of California. All Rights Reserved. diff --git a/driver/windows/sys/makefile.inc b/driver/windows/sys/makefile.inc index 7d1cd6a..760f5c4 100755 --- a/driver/windows/sys/makefile.inc +++ b/driver/windows/sys/makefile.inc @@ -22,7 +22,7 @@ POST: inf2cat /driver:$(OBJ_PATH)\$(O) /os:7_x64 ! endif ! endif - signtool sign /v /ac "$(_INX)\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll $(OBJ_PATH)\$(O)\$(INF_NAME).cat - signtool sign /v /ac "$(_INX)\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll $(OBJ_PATH)\$(O)\$(INF_NAME).sys + signtool sign /v /ac "$(_INX)\..\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll $(OBJ_PATH)\$(O)\$(INF_NAME).cat + signtool sign /v /ac "$(_INX)\..\GlobalSign Root CA.crt" /s my /n "University of California, San Diego" /t http://timestamp.verisign.com/scripts/timestamp.dll $(OBJ_PATH)\$(O)\$(INF_NAME).sys \ No newline at end of file diff --git a/fpga/riffa_hdl/tx_port_channel_gate_128.v b/fpga/riffa_hdl/tx_port_channel_gate_128.v index 0885389..42b4649 100644 --- a/fpga/riffa_hdl/tx_port_channel_gate_128.v +++ b/fpga/riffa_hdl/tx_port_channel_gate_128.v @@ -33,189 +33,169 @@ // DAMAGE. // ---------------------------------------------------------------------- //---------------------------------------------------------------------------- -// Filename: tx_port_channel_gate_128.v -// Version: 1.00.a -// Verilog Standard: Verilog-2001 -// Description: Captures transaction open/close events as well as data +// Filename: tx_port_channel_gate_128.v +// Version: 1.00.a +// Verilog Standard: Verilog-2001 +// Description: Captures transaction open/close events as well as data // and passes it to the RD_CLK domain through the async_fifo. CHNL_TX_DATA_REN can // only be high after CHNL_TX goes high and after the CHNL_TX_ACK pulse. When // CHNL_TX drops, the channel closes (until the next transaction -- signaled by // CHNL_TX going up again). -// Author: Matt Jacobsen -// History: @mattj: Version 2.0 +// Author: Matt Jacobsen +// History: @mattj: Version 2.0 //----------------------------------------------------------------------------- -`define S_TXPORTGATE128_IDLE 2'b00 -`define S_TXPORTGATE128_OPENING 2'b01 -`define S_TXPORTGATE128_OPEN 2'b10 -`define S_TXPORTGATE128_CLOSED 2'b11 +`define S_TXPORTGATE128_IDLE 2'b00 +`define S_TXPORTGATE128_OPENING 2'b01 +`define S_TXPORTGATE128_OPEN 2'b10 +`define S_TXPORTGATE128_CLOSED 2'b11 `timescale 1ns/1ns -module tx_port_channel_gate_128 #( - parameter C_DATA_WIDTH = 9'd128, - // Local parameters - parameter C_FIFO_DEPTH = 8, - parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH+1 -) -( - input RST, +module tx_port_channel_gate_128 + #(parameter C_DATA_WIDTH = 9'd128, + // Local parameters + parameter C_FIFO_DEPTH = 8, + parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH + 1) + (input RST, - input RD_CLK, // FIFO read clock - output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data - output RD_EMPTY, // FIFO is empty - input RD_EN, // FIFO read enable + input RD_CLK, // FIFO read clock + output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data + output RD_EMPTY, // FIFO is empty + input RD_EN, // FIFO read enable - input CHNL_CLK, // Channel write clock - input CHNL_TX, // Channel write receive signal - output CHNL_TX_ACK, // Channel write acknowledgement signal - input CHNL_TX_LAST, // Channel last write - input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) - input [30:0] CHNL_TX_OFF, // Channel write offset - input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data - input CHNL_TX_DATA_VALID, // Channel write data valid - output CHNL_TX_DATA_REN // Channel write data has been recieved -); + input CHNL_CLK, // Channel write clock + input CHNL_TX, // Channel write receive signal + output CHNL_TX_ACK, // Channel write acknowledgement signal + input CHNL_TX_LAST, // Channel last write + input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) + input [30:0] CHNL_TX_OFF, // Channel write offset + input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data + input CHNL_TX_DATA_VALID, // Channel write data valid + output CHNL_TX_DATA_REN); // Channel write data has been recieved -(* syn_encoding = "user" *) -(* fsm_encoding = "user" *) -reg [1:0] rState=`S_TXPORTGATE128_IDLE, _rState=`S_TXPORTGATE128_IDLE; -reg rFifoWen=0, _rFifoWen=0; -reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; -wire wFifoFull; + (* syn_encoding = "user" *) + (* fsm_encoding = "user" *) + reg [1:0] rState=`S_TXPORTGATE128_IDLE, _rState=`S_TXPORTGATE128_IDLE; + reg rFifoWen=0, _rFifoWen=0; + reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; + wire wFifoFull; -reg rChnlTx=0, _rChnlTx=0; -reg rChnlLast=0, _rChnlLast=0; -reg [31:0] rChnlLen=0, _rChnlLen=0; -reg [30:0] rChnlOff=0, _rChnlOff=0; -reg rAck=0, _rAck=0; -reg rPause=0, _rPause=0; -reg rClosed=0, _rClosed=0; + reg rChnlTx=0, _rChnlTx=0; + reg rChnlLast=0, _rChnlLast=0; + reg [31:0] rChnlLen=0, _rChnlLen=0; + reg [30:0] rChnlOff=0, _rChnlOff=0; + reg rAck=0, _rAck=0; + reg rPause=0, _rPause=0; + reg rClosed=0, _rClosed=0; + reg rOpen=0, _rOpen=0; + assign CHNL_TX_ACK = rAck; + assign CHNL_TX_DATA_REN = (rOpen & !wFifoFull); // S_TXPORTGATE128_OPEN -assign CHNL_TX_ACK = rAck; -assign CHNL_TX_DATA_REN = (rState[1] & !rState[0] & !wFifoFull); // S_TXPORTGATE128_OPEN + // Buffer the input signals that come from outside the tx_port. + always @ (posedge CHNL_CLK) begin + rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); + rChnlLast <= #1 _rChnlLast; + rChnlLen <= #1 _rChnlLen; + rChnlOff <= #1 _rChnlOff; + end + always @ (*) begin + _rChnlTx = CHNL_TX; + _rChnlLast = CHNL_TX_LAST; + _rChnlLen = CHNL_TX_LEN; + _rChnlOff = CHNL_TX_OFF; + end -// Buffer the input signals that come from outside the tx_port. -always @ (posedge CHNL_CLK) begin - rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); - rChnlLast <= #1 _rChnlLast; - rChnlLen <= #1 _rChnlLen; - rChnlOff <= #1 _rChnlOff; -end + // FIFO for temporarily storing data from the channel. + (* RAM_STYLE="DISTRIBUTED" *) + async_fifo + #(.C_WIDTH(C_FIFO_DATA_WIDTH), + .C_DEPTH(C_FIFO_DEPTH)) + fifo + (.WR_CLK(CHNL_CLK), + .WR_RST(RST), + .WR_EN(rFifoWen), + .WR_DATA(rFifoData), + .WR_FULL(wFifoFull), + .RD_CLK(RD_CLK), + .RD_RST(RST), + .RD_EN(RD_EN), + .RD_DATA(RD_DATA), + .RD_EMPTY(RD_EMPTY)); -always @ (*) begin - _rChnlTx = CHNL_TX; - _rChnlLast = CHNL_TX_LAST; - _rChnlLen = CHNL_TX_LEN; - _rChnlOff = CHNL_TX_OFF; -end + // Pass the transaction open event, transaction data, and the transaction + // close event through to the RD_CLK domain via the async_fifo. + always @ (posedge CHNL_CLK) begin + rState <= #1 (RST ? `S_TXPORTGATE128_IDLE : _rState); + rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); + rFifoData <= #1 _rFifoData; + rAck <= #1 (RST ? 1'd0 : _rAck); + rPause <= #1 (RST ? 1'd0 : _rPause); + rClosed <= #1 (RST ? 1'd0 : _rClosed); + rOpen <= #1 (RST ? 1'd0 : _rOpen); + end + always @ (*) begin + _rState = rState; + _rFifoWen = rFifoWen; + _rFifoData = rFifoData; + _rPause = rPause; + _rAck = rAck; + _rClosed = rClosed; + _rOpen = rOpen; + case (rState) -// FIFO for temporarily storing data from the channel. -(* RAM_STYLE="DISTRIBUTED" *) -async_fifo #(.C_WIDTH(C_FIFO_DATA_WIDTH), .C_DEPTH(C_FIFO_DEPTH)) fifo ( - .WR_CLK(CHNL_CLK), - .WR_RST(RST), - .WR_EN(rFifoWen), - .WR_DATA(rFifoData), - .WR_FULL(wFifoFull), - .RD_CLK(RD_CLK), - .RD_RST(RST), - .RD_EN(RD_EN), - .RD_DATA(RD_DATA), - .RD_EMPTY(RD_EMPTY) -); + `S_TXPORTGATE128_IDLE: begin // Write the len, off, last + _rPause = 0; + _rClosed = 0; + _rOpen = 0; + if (!wFifoFull) begin + _rAck = rChnlTx; + _rFifoWen = rChnlTx; + _rFifoData = {1'd1, 64'd0, rChnlLen, rChnlOff, rChnlLast}; + if (rChnlTx) + _rState = `S_TXPORTGATE128_OPENING; + end + end + `S_TXPORTGATE128_OPENING: begin // Write the len, off, last (again) + _rAck = 0; + // rClosed catches a transfer that opens and subsequently closes + // without writing data + _rClosed = (rClosed | !rChnlTx); + if (!wFifoFull) begin + if (rClosed | !rChnlTx) + _rState = `S_TXPORTGATE128_CLOSED; + else begin + _rState = `S_TXPORTGATE128_OPEN; + _rOpen = CHNL_TX & rChnlTx; + end + end + end -// Pass the transaction open event, transaction data, and the transaction -// close event through to the RD_CLK domain via the async_fifo. -always @ (posedge CHNL_CLK) begin - rState <= #1 (RST ? `S_TXPORTGATE128_IDLE : _rState); - rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); - rFifoData <= #1 _rFifoData; - rAck <= #1 (RST ? 1'd0 : _rAck); - rPause <= #1 (RST ? 1'd0 : _rPause); - rClosed <= #1 (RST ? 1'd0 : _rClosed); -end - -always @ (*) begin - _rState = rState; - _rFifoWen = rFifoWen; - _rFifoData = rFifoData; - _rPause = rPause; - _rAck = rAck; - _rClosed = rClosed; - case (rState) - - `S_TXPORTGATE128_IDLE: begin // Write the len, off, last - _rPause = 0; - _rClosed = 0; - if (!wFifoFull) begin - _rAck = rChnlTx; - _rFifoWen = rChnlTx; - _rFifoData = {1'd1, 64'd0, rChnlLen, rChnlOff, rChnlLast}; - if (rChnlTx) - _rState = `S_TXPORTGATE128_OPENING; - end - end - - `S_TXPORTGATE128_OPENING: begin // Write the len, off, last (again) - _rAck = 0; - _rClosed = (rClosed | !rChnlTx); - if (!wFifoFull) begin - if (rClosed | !rChnlTx) - _rState = `S_TXPORTGATE128_CLOSED; - else - _rState = `S_TXPORTGATE128_OPEN; - end - end - - `S_TXPORTGATE128_OPEN: begin // Copy channel data into the FIFO - if (!wFifoFull) begin - _rFifoWen = CHNL_TX_DATA_VALID; // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered - _rFifoData = {1'd0, CHNL_TX_DATA}; // but the VALID+REN model seem to make this difficult. - end - if (!rChnlTx) - _rState = `S_TXPORTGATE128_CLOSED; - end - - `S_TXPORTGATE128_CLOSED: begin // Write the end marker (twice) - if (!wFifoFull) begin - _rPause = 1; - _rFifoWen = 1; - _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; - if (rPause) - _rState = `S_TXPORTGATE128_IDLE; - end - end - - endcase -end - -/* -wire [35:0] wControl0; -chipscope_icon_1 cs_icon( - .CONTROL0(wControl0) -); - -chipscope_ila_t8_512 a0( - .CLK(CHNL_CLK), - .CONTROL(wControl0), - .TRIG0({4'd0, wFifoFull, CHNL_TX, rState}), - .DATA({313'd0, - rChnlOff, // 31 - rChnlLen, // 32 - rChnlLast, // 1 - rChnlTx, // 1 - CHNL_TX_OFF, // 31 - CHNL_TX_LEN, // 32 - CHNL_TX_LAST, // 1 - CHNL_TX, // 1 - wFifoFull, // 1 - rFifoData, // 65 - rFifoWen, // 1 - rState}) // 2 -); -*/ + `S_TXPORTGATE128_OPEN: begin // Copy channel data into the FIFO + if (!wFifoFull) begin + // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered + // but the VALID+REN model seem to make this difficult. + _rFifoWen = CHNL_TX_DATA_VALID; + _rFifoData = {1'd0, CHNL_TX_DATA}; + end + if (!rChnlTx) + _rState = `S_TXPORTGATE128_CLOSED; + _rOpen = CHNL_TX & rChnlTx; + end + + `S_TXPORTGATE128_CLOSED: begin // Write the end marker (twice) + if (!wFifoFull) begin + _rPause = 1; + _rFifoWen = 1; + _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; + if (rPause) + _rState = `S_TXPORTGATE128_IDLE; + end + end + + endcase + end endmodule diff --git a/fpga/riffa_hdl/tx_port_channel_gate_32.v b/fpga/riffa_hdl/tx_port_channel_gate_32.v index 98314e1..1256d24 100644 --- a/fpga/riffa_hdl/tx_port_channel_gate_32.v +++ b/fpga/riffa_hdl/tx_port_channel_gate_32.v @@ -33,191 +33,172 @@ // DAMAGE. // ---------------------------------------------------------------------- //---------------------------------------------------------------------------- -// Filename: tx_port_channel_gate_32.v -// Version: 1.00.a -// Verilog Standard: Verilog-2001 -// Description: Captures transaction open/close events as well as data +// Filename: tx_port_channel_gate_32.v +// Version: 1.00.a +// Verilog Standard: Verilog-2001 +// Description: Captures transaction open/close events as well as data // and passes it to the RD_CLK domain through the async_fifo. CHNL_TX_DATA_REN can // only be high after CHNL_TX goes high and after the CHNL_TX_ACK pulse. When // CHNL_TX drops, the channel closes (until the next transaction -- signaled by // CHNL_TX going up again). -// Author: Matt Jacobsen -// History: @mattj: Version 2.0 +// Author: Matt Jacobsen +// History: @mattj: Version 2.0 //----------------------------------------------------------------------------- -`define S_TXPORTGATE32_IDLE 2'b00 -`define S_TXPORTGATE32_OPENING 2'b01 -`define S_TXPORTGATE32_OPEN 2'b10 -`define S_TXPORTGATE32_CLOSED 2'b11 +`define S_TXPORTGATE32_IDLE 2'b00 +`define S_TXPORTGATE32_OPENING 2'b01 +`define S_TXPORTGATE32_OPEN 2'b10 +`define S_TXPORTGATE32_CLOSED 2'b11 `timescale 1ns/1ns -module tx_port_channel_gate_32 #( - parameter C_DATA_WIDTH = 9'd32, - // Local parameters - parameter C_FIFO_DEPTH = 8, - parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH+1 -) -( - input RST, +module tx_port_channel_gate_32 + #(parameter C_DATA_WIDTH = 9'd32, + // Local parameters + parameter C_FIFO_DEPTH = 8, + parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH + 1) + (input RST, - input RD_CLK, // FIFO read clock - output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data - output RD_EMPTY, // FIFO is empty - input RD_EN, // FIFO read enable + input RD_CLK, // FIFO read clock + output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data + output RD_EMPTY, // FIFO is empty + input RD_EN, // FIFO read enable - input CHNL_CLK, // Channel write clock - input CHNL_TX, // Channel write receive signal - output CHNL_TX_ACK, // Channel write acknowledgement signal - input CHNL_TX_LAST, // Channel last write - input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) - input [30:0] CHNL_TX_OFF, // Channel write offset - input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data - input CHNL_TX_DATA_VALID, // Channel write data valid - output CHNL_TX_DATA_REN // Channel write data has been recieved -); + input CHNL_CLK, // Channel write clock + input CHNL_TX, // Channel write receive signal + output CHNL_TX_ACK, // Channel write acknowledgement signal + input CHNL_TX_LAST, // Channel last write + input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) + input [30:0] CHNL_TX_OFF, // Channel write offset + input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data + input CHNL_TX_DATA_VALID, // Channel write data valid + output CHNL_TX_DATA_REN); // Channel write data has been recieved -(* syn_encoding = "user" *) -(* fsm_encoding = "user" *) -reg [1:0] rState=`S_TXPORTGATE32_IDLE, _rState=`S_TXPORTGATE32_IDLE; -reg rFifoWen=0, _rFifoWen=0; -reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; -wire wFifoFull; + (* syn_encoding = "user" *) + (* fsm_encoding = "user" *) + reg [1:0] rState=`S_TXPORTGATE32_IDLE, _rState=`S_TXPORTGATE32_IDLE; + reg rFifoWen=0, _rFifoWen=0; + reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; + wire wFifoFull; -reg rChnlTx=0, _rChnlTx=0; -reg rChnlLast=0, _rChnlLast=0; -reg [31:0] rChnlLen=0, _rChnlLen=0; -reg [30:0] rChnlOff=0, _rChnlOff=0; -reg rAck=0, _rAck=0; -reg rPause=0, _rPause=0; -reg rClosed=0, _rClosed=0; + reg rChnlTx=0, _rChnlTx=0; + reg rChnlLast=0, _rChnlLast=0; + reg [31:0] rChnlLen=0, _rChnlLen=0; + reg [30:0] rChnlOff=0, _rChnlOff=0; + reg rAck=0, _rAck=0; + reg rPause=0, _rPause=0; + reg rClosed=0, _rClosed=0; + reg rOpen=0, _rOpen=0; + assign CHNL_TX_ACK = rAck; + assign CHNL_TX_DATA_REN = (rOpen & !wFifoFull); // S_TXPORTGATE32_OPEN -assign CHNL_TX_ACK = rAck; -assign CHNL_TX_DATA_REN = (rState[1] & !rState[0] & !wFifoFull); // S_TXPORTGATE32_OPEN + // Buffer the input signals that come from outside the tx_port. + always @ (posedge CHNL_CLK) begin + rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); + rChnlLast <= #1 _rChnlLast; + rChnlLen <= #1 _rChnlLen; + rChnlOff <= #1 _rChnlOff; + end + always @ (*) begin + _rChnlTx = CHNL_TX; + _rChnlLast = CHNL_TX_LAST; + _rChnlLen = CHNL_TX_LEN; + _rChnlOff = CHNL_TX_OFF; + end -// Buffer the input signals that come from outside the tx_port. -always @ (posedge CHNL_CLK) begin - rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); - rChnlLast <= #1 _rChnlLast; - rChnlLen <= #1 _rChnlLen; - rChnlOff <= #1 _rChnlOff; -end + // FIFO for temporarily storing data from the channel. + (* RAM_STYLE="DISTRIBUTED" *) + async_fifo + #(.C_WIDTH(C_FIFO_DATA_WIDTH), + .C_DEPTH(C_FIFO_DEPTH)) + fifo + (.WR_CLK(CHNL_CLK), + .WR_RST(RST), + .WR_EN(rFifoWen), + .WR_DATA(rFifoData), + .WR_FULL(wFifoFull), + .RD_CLK(RD_CLK), + .RD_RST(RST), + .RD_EN(RD_EN), + .RD_DATA(RD_DATA), + .RD_EMPTY(RD_EMPTY)); -always @ (*) begin - _rChnlTx = CHNL_TX; - _rChnlLast = CHNL_TX_LAST; - _rChnlLen = CHNL_TX_LEN; - _rChnlOff = CHNL_TX_OFF; -end + // Pass the transaction open event, transaction data, and the transaction + // close event through to the RD_CLK domain via the async_fifo. + always @ (posedge CHNL_CLK) begin + rState <= #1 (RST ? `S_TXPORTGATE32_IDLE : _rState); + rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); + rFifoData <= #1 _rFifoData; + rAck <= #1 (RST ? 1'd0 : _rAck); + rPause <= #1 (RST ? 1'd0 : _rPause); + rClosed <= #1 (RST ? 1'd0 : _rClosed); + rOpen <= #1 (RST ? 1'd0 : _rOpen); + end + always @ (*) begin + _rState = rState; + _rFifoWen = rFifoWen; + _rFifoData = rFifoData; + _rPause = rPause; + _rAck = rAck; + _rClosed = rClosed; + _rOpen = rOpen; + case (rState) -// FIFO for temporarily storing data from the channel. -(* RAM_STYLE="DISTRIBUTED" *) -async_fifo #(.C_WIDTH(C_FIFO_DATA_WIDTH), .C_DEPTH(C_FIFO_DEPTH)) fifo ( - .WR_CLK(CHNL_CLK), - .WR_RST(RST), - .WR_EN(rFifoWen), - .WR_DATA(rFifoData), - .WR_FULL(wFifoFull), - .RD_CLK(RD_CLK), - .RD_RST(RST), - .RD_EN(RD_EN), - .RD_DATA(RD_DATA), - .RD_EMPTY(RD_EMPTY) -); + `S_TXPORTGATE32_IDLE: begin // Write the len + _rPause = 0; + _rClosed = 0; + _rOpen = 0; + if (!wFifoFull) begin + _rFifoWen = rChnlTx; + _rFifoData = {1'd1, rChnlLen}; + if (rChnlTx) + _rState = `S_TXPORTGATE32_OPENING; + end + end + `S_TXPORTGATE32_OPENING: begin // Write the off, last + // rClosed catches a transfer that opens and subsequently closes + // without writing data + _rClosed = (rClosed | !rChnlTx); + if (!wFifoFull) begin + _rAck = rChnlTx; + _rFifoData = {1'd1, rChnlOff, rChnlLast}; + if (rClosed | !rChnlTx) + _rState = `S_TXPORTGATE32_CLOSED; + else begin + _rState = `S_TXPORTGATE32_OPEN; + _rOpen = CHNL_TX & rChnlTx; + end + end + end -// Pass the transaction open event, transaction data, and the transaction -// close event through to the RD_CLK domain via the async_fifo. -always @ (posedge CHNL_CLK) begin - rState <= #1 (RST ? `S_TXPORTGATE32_IDLE : _rState); - rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); - rFifoData <= #1 _rFifoData; - rAck <= #1 (RST ? 1'd0 : _rAck); - rPause <= #1 (RST ? 1'd0 : _rPause); - rClosed <= #1 (RST ? 1'd0 : _rClosed); -end + `S_TXPORTGATE32_OPEN: begin // Copy channel data into the FIFO + _rAck = 0; + if (!wFifoFull) begin + // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered + // but the VALID+REN model seem to make this difficult. + _rFifoWen = CHNL_TX_DATA_VALID; + _rFifoData = {1'd0, CHNL_TX_DATA}; + end + if (!rChnlTx) + _rState = `S_TXPORTGATE32_CLOSED; + _rOpen = CHNL_TX & rChnlTx; + end + + `S_TXPORTGATE32_CLOSED: begin // Write the end marker (twice) + _rAck = 0; + if (!wFifoFull) begin + _rPause = 1; + _rFifoWen = 1; + _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; + if (rPause) + _rState = `S_TXPORTGATE32_IDLE; + end + end + + endcase -always @ (*) begin - _rState = rState; - _rFifoWen = rFifoWen; - _rFifoData = rFifoData; - _rPause = rPause; - _rAck = rAck; - _rClosed = rClosed; - case (rState) - - `S_TXPORTGATE32_IDLE: begin // Write the len - _rPause = 0; - _rClosed = 0; - if (!wFifoFull) begin - _rFifoWen = rChnlTx; - _rFifoData = {1'd1, rChnlLen}; - if (rChnlTx) - _rState = `S_TXPORTGATE32_OPENING; - end - end - - `S_TXPORTGATE32_OPENING: begin // Write the off, last - _rClosed = (rClosed | !rChnlTx); - if (!wFifoFull) begin - _rAck = rChnlTx; - _rFifoData = {1'd1, rChnlOff, rChnlLast}; - if (rClosed | !rChnlTx) - _rState = `S_TXPORTGATE32_CLOSED; - else - _rState = `S_TXPORTGATE32_OPEN; - end - end - - `S_TXPORTGATE32_OPEN: begin // Copy channel data into the FIFO - _rAck = 0; - if (!wFifoFull) begin - _rFifoWen = CHNL_TX_DATA_VALID; // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered - _rFifoData = {1'd0, CHNL_TX_DATA}; // but the VALID+REN model seem to make this difficult. - end - if (!rChnlTx) - _rState = `S_TXPORTGATE32_CLOSED; - end - - `S_TXPORTGATE32_CLOSED: begin // Write the end marker (twice) - _rAck = 0; - if (!wFifoFull) begin - _rPause = 1; - _rFifoWen = 1; - _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; - if (rPause) - _rState = `S_TXPORTGATE32_IDLE; - end - end - - endcase -end - -/* -wire [35:0] wControl0; -chipscope_icon_1 cs_icon( - .CONTROL0(wControl0) -); - -chipscope_ila_t8_512 a0( - .CLK(CHNL_CLK), - .CONTROL(wControl0), - .TRIG0({4'd0, wFifoFull, CHNL_TX, rState}), - .DATA({313'd0, - rChnlOff, // 31 - rChnlLen, // 32 - rChnlLast, // 1 - rChnlTx, // 1 - CHNL_TX_OFF, // 31 - CHNL_TX_LEN, // 32 - CHNL_TX_LAST, // 1 - CHNL_TX, // 1 - wFifoFull, // 1 - rFifoData, // 65 - rFifoWen, // 1 - rState}) // 2 -); -*/ + end endmodule diff --git a/fpga/riffa_hdl/tx_port_channel_gate_64.v b/fpga/riffa_hdl/tx_port_channel_gate_64.v index 4e5712a..bd9ef0e 100644 --- a/fpga/riffa_hdl/tx_port_channel_gate_64.v +++ b/fpga/riffa_hdl/tx_port_channel_gate_64.v @@ -33,189 +33,169 @@ // DAMAGE. // ---------------------------------------------------------------------- //---------------------------------------------------------------------------- -// Filename: tx_port_channel_gate_64.v -// Version: 1.00.a -// Verilog Standard: Verilog-2001 -// Description: Captures transaction open/close events as well as data +// Filename: tx_port_channel_gate_64.v +// Version: 1.00.a +// Verilog Standard: Verilog-2001 +// Description: Captures transaction open/close events as well as data // and passes it to the RD_CLK domain through the async_fifo. CHNL_TX_DATA_REN can // only be high after CHNL_TX goes high and after the CHNL_TX_ACK pulse. When // CHNL_TX drops, the channel closes (until the next transaction -- signaled by // CHNL_TX going up again). -// Author: Matt Jacobsen -// History: @mattj: Version 2.0 +// Author: Matt Jacobsen +// History: @mattj: Version 2.0 //----------------------------------------------------------------------------- -`define S_TXPORTGATE64_IDLE 2'b00 -`define S_TXPORTGATE64_OPENING 2'b01 -`define S_TXPORTGATE64_OPEN 2'b10 -`define S_TXPORTGATE64_CLOSED 2'b11 +`define S_TXPORTGATE64_IDLE 2'b00 +`define S_TXPORTGATE64_OPENING 2'b01 +`define S_TXPORTGATE64_OPEN 2'b10 +`define S_TXPORTGATE64_CLOSED 2'b11 `timescale 1ns/1ns -module tx_port_channel_gate_64 #( - parameter C_DATA_WIDTH = 9'd64, - // Local parameters - parameter C_FIFO_DEPTH = 8, - parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH+1 -) -( - input RST, +module tx_port_channel_gate_64 + #(parameter C_DATA_WIDTH = 9'd64, + // Local parameters + parameter C_FIFO_DEPTH = 8, + parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH + 1) + (input RST, - input RD_CLK, // FIFO read clock - output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data - output RD_EMPTY, // FIFO is empty - input RD_EN, // FIFO read enable + input RD_CLK, // FIFO read clock + output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data + output RD_EMPTY, // FIFO is empty + input RD_EN, // FIFO read enable - input CHNL_CLK, // Channel write clock - input CHNL_TX, // Channel write receive signal - output CHNL_TX_ACK, // Channel write acknowledgement signal - input CHNL_TX_LAST, // Channel last write - input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) - input [30:0] CHNL_TX_OFF, // Channel write offset - input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data - input CHNL_TX_DATA_VALID, // Channel write data valid - output CHNL_TX_DATA_REN // Channel write data has been recieved -); + input CHNL_CLK, // Channel write clock + input CHNL_TX, // Channel write receive signal + output CHNL_TX_ACK, // Channel write acknowledgement signal + input CHNL_TX_LAST, // Channel last write + input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words) + input [30:0] CHNL_TX_OFF, // Channel write offset + input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data + input CHNL_TX_DATA_VALID, // Channel write data valid + output CHNL_TX_DATA_REN); // Channel write data has been recieved -(* syn_encoding = "user" *) -(* fsm_encoding = "user" *) -reg [1:0] rState=`S_TXPORTGATE64_IDLE, _rState=`S_TXPORTGATE64_IDLE; -reg rFifoWen=0, _rFifoWen=0; -reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; -wire wFifoFull; + (* syn_encoding = "user" *) + (* fsm_encoding = "user" *) + reg [1:0] rState=`S_TXPORTGATE64_IDLE, _rState=`S_TXPORTGATE64_IDLE; + reg rFifoWen=0, _rFifoWen=0; + reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0; + wire wFifoFull; -reg rChnlTx=0, _rChnlTx=0; -reg rChnlLast=0, _rChnlLast=0; -reg [31:0] rChnlLen=0, _rChnlLen=0; -reg [30:0] rChnlOff=0, _rChnlOff=0; -reg rAck=0, _rAck=0; -reg rPause=0, _rPause=0; -reg rClosed=0, _rClosed=0; + reg rChnlTx=0, _rChnlTx=0; + reg rChnlLast=0, _rChnlLast=0; + reg [31:0] rChnlLen=0, _rChnlLen=0; + reg [30:0] rChnlOff=0, _rChnlOff=0; + reg rAck=0, _rAck=0; + reg rPause=0, _rPause=0; + reg rClosed=0, _rClosed=0; + reg rOpen=0, _rOpen=0; + assign CHNL_TX_ACK = rAck; + assign CHNL_TX_DATA_REN = (rOpen & !wFifoFull); // S_TXPORTGATE128_OPEN -assign CHNL_TX_ACK = rAck; -assign CHNL_TX_DATA_REN = (rState[1] & !rState[0] & !wFifoFull); // S_TXPORTGATE64_OPEN + // Buffer the input signals that come from outside the tx_port. + always @ (posedge CHNL_CLK) begin + rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); + rChnlLast <= #1 _rChnlLast; + rChnlLen <= #1 _rChnlLen; + rChnlOff <= #1 _rChnlOff; + end + always @ (*) begin + _rChnlTx = CHNL_TX; + _rChnlLast = CHNL_TX_LAST; + _rChnlLen = CHNL_TX_LEN; + _rChnlOff = CHNL_TX_OFF; + end -// Buffer the input signals that come from outside the tx_port. -always @ (posedge CHNL_CLK) begin - rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx); - rChnlLast <= #1 _rChnlLast; - rChnlLen <= #1 _rChnlLen; - rChnlOff <= #1 _rChnlOff; -end + // FIFO for temporarily storing data from the channel. + (* RAM_STYLE="DISTRIBUTED" *) + async_fifo + #(.C_WIDTH(C_FIFO_DATA_WIDTH), + .C_DEPTH(C_FIFO_DEPTH)) + fifo + (.WR_CLK(CHNL_CLK), + .WR_RST(RST), + .WR_EN(rFifoWen), + .WR_DATA(rFifoData), + .WR_FULL(wFifoFull), + .RD_CLK(RD_CLK), + .RD_RST(RST), + .RD_EN(RD_EN), + .RD_DATA(RD_DATA), + .RD_EMPTY(RD_EMPTY)); -always @ (*) begin - _rChnlTx = CHNL_TX; - _rChnlLast = CHNL_TX_LAST; - _rChnlLen = CHNL_TX_LEN; - _rChnlOff = CHNL_TX_OFF; -end + // Pass the transaction open event, transaction data, and the transaction + // close event through to the RD_CLK domain via the async_fifo. + always @ (posedge CHNL_CLK) begin + rState <= #1 (RST ? `S_TXPORTGATE64_IDLE : _rState); + rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); + rFifoData <= #1 _rFifoData; + rAck <= #1 (RST ? 1'd0 : _rAck); + rPause <= #1 (RST ? 1'd0 : _rPause); + rClosed <= #1 (RST ? 1'd0 : _rClosed); + rOpen <= #1 (RST ? 1'd0 : _rOpen); + end + always @ (*) begin + _rState = rState; + _rFifoWen = rFifoWen; + _rFifoData = rFifoData; + _rPause = rPause; + _rAck = rAck; + _rClosed = rClosed; + _rOpen = rOpen; + case (rState) -// FIFO for temporarily storing data from the channel. -(* RAM_STYLE="DISTRIBUTED" *) -async_fifo #(.C_WIDTH(C_FIFO_DATA_WIDTH), .C_DEPTH(C_FIFO_DEPTH)) fifo ( - .WR_CLK(CHNL_CLK), - .WR_RST(RST), - .WR_EN(rFifoWen), - .WR_DATA(rFifoData), - .WR_FULL(wFifoFull), - .RD_CLK(RD_CLK), - .RD_RST(RST), - .RD_EN(RD_EN), - .RD_DATA(RD_DATA), - .RD_EMPTY(RD_EMPTY) -); + `S_TXPORTGATE64_IDLE: begin // Write the len, off, last + _rPause = 0; + _rClosed = 0; + _rOpen = 0; + if (!wFifoFull) begin + _rAck = rChnlTx; + _rFifoWen = rChnlTx; + _rFifoData = {1'd1, rChnlLen, rChnlOff, rChnlLast}; + if (rChnlTx) + _rState = `S_TXPORTGATE64_OPENING; + end + end + `S_TXPORTGATE64_OPENING: begin // Write the len, off, last (again) + _rAck = 0; + // rClosed catches a transfer that opens and subsequently closes + // without writing data + _rClosed = (rClosed | !rChnlTx); + if (!wFifoFull) begin + if (rClosed | !rChnlTx) + _rState = `S_TXPORTGATE64_CLOSED; + else begin + _rState = `S_TXPORTGATE64_OPEN; + _rOpen = CHNL_TX & rChnlTx; + end + end + end -// Pass the transaction open event, transaction data, and the transaction -// close event through to the RD_CLK domain via the async_fifo. -always @ (posedge CHNL_CLK) begin - rState <= #1 (RST ? `S_TXPORTGATE64_IDLE : _rState); - rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen); - rFifoData <= #1 _rFifoData; - rAck <= #1 (RST ? 1'd0 : _rAck); - rPause <= #1 (RST ? 1'd0 : _rPause); - rClosed <= #1 (RST ? 1'd0 : _rClosed); -end - -always @ (*) begin - _rState = rState; - _rFifoWen = rFifoWen; - _rFifoData = rFifoData; - _rPause = rPause; - _rAck = rAck; - _rClosed = rClosed; - case (rState) - - `S_TXPORTGATE64_IDLE: begin // Write the len, off, last - _rPause = 0; - _rClosed = 0; - if (!wFifoFull) begin - _rAck = rChnlTx; - _rFifoWen = rChnlTx; - _rFifoData = {1'd1, rChnlLen, rChnlOff, rChnlLast}; - if (rChnlTx) - _rState = `S_TXPORTGATE64_OPENING; - end - end - - `S_TXPORTGATE64_OPENING: begin // Write the len, off, last (again) - _rAck = 0; - _rClosed = (rClosed | !rChnlTx); - if (!wFifoFull) begin - if (rClosed | !rChnlTx) - _rState = `S_TXPORTGATE64_CLOSED; - else - _rState = `S_TXPORTGATE64_OPEN; - end - end - - `S_TXPORTGATE64_OPEN: begin // Copy channel data into the FIFO - if (!wFifoFull) begin - _rFifoWen = CHNL_TX_DATA_VALID; // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered - _rFifoData = {1'd0, CHNL_TX_DATA}; // but the VALID+REN model seem to make this difficult. - end - if (!rChnlTx) - _rState = `S_TXPORTGATE64_CLOSED; - end - - `S_TXPORTGATE64_CLOSED: begin // Write the end marker (twice) - if (!wFifoFull) begin - _rPause = 1; - _rFifoWen = 1; - _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; - if (rPause) - _rState = `S_TXPORTGATE64_IDLE; - end - end - - endcase -end - -/* -wire [35:0] wControl0; -chipscope_icon_1 cs_icon( - .CONTROL0(wControl0) -); - -chipscope_ila_t8_512 a0( - .CLK(CHNL_CLK), - .CONTROL(wControl0), - .TRIG0({4'd0, wFifoFull, CHNL_TX, rState}), - .DATA({313'd0, - rChnlOff, // 31 - rChnlLen, // 32 - rChnlLast, // 1 - rChnlTx, // 1 - CHNL_TX_OFF, // 31 - CHNL_TX_LEN, // 32 - CHNL_TX_LAST, // 1 - CHNL_TX, // 1 - wFifoFull, // 1 - rFifoData, // 65 - rFifoWen, // 1 - rState}) // 2 -); -*/ + `S_TXPORTGATE64_OPEN: begin // Copy channel data into the FIFO + if (!wFifoFull) begin + // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered + // but the VALID+REN model seem to make this difficult. + _rFifoWen = CHNL_TX_DATA_VALID; + _rFifoData = {1'd0, CHNL_TX_DATA}; + end + if (!rChnlTx) + _rState = `S_TXPORTGATE64_CLOSED; + _rOpen = CHNL_TX & rChnlTx; + end + + `S_TXPORTGATE64_CLOSED: begin // Write the end marker (twice) + if (!wFifoFull) begin + _rPause = 1; + _rFifoWen = 1; + _rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}}; + if (rPause) + _rState = `S_TXPORTGATE64_IDLE; + end + end + + endcase + end endmodule diff --git a/python/riffa.py b/python/riffa.py index 1213677..565cb6d 100644 --- a/python/riffa.py +++ b/python/riffa.py @@ -48,6 +48,9 @@ if platform.system() == "Linux": else: libriffa = ctypes.CDLL("riffa.dll") +libriffa.fpga_recv.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_longlong] +libriffa.fpga_send.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_longlong] + class FpgaInfoList(ctypes.Structure): _fields_ = [("num_fpgas", ctypes.c_int), ("id", ctypes.c_int * NUM_FPGAS), @@ -156,7 +159,7 @@ def fpga_recv(fd, chnl, data, timeout): ctypes.pythonapi.PyObject_AsReadBuffer(obj, ctypes.byref(a), ctypes.byref(l)) ptr = a.value datalen = l.value - return libriffa.fpga_recv(fd, chnl, ptr, datalen/4, timeout) + return libriffa.fpga_recv(fd, chnl, ptr, datalen//4, timeout) # Resets the state of the FPGA and all transfers across all channels. This is