From 58fd605f35ef786e6c18d9403ad6692da3fbe0b3 Mon Sep 17 00:00:00 2001 From: Jonathan O'Brien Date: Mon, 28 Mar 2016 10:50:08 -0700 Subject: [PATCH 1/8] Add support for 64 bit arch and python 3 Added signature to pass *data as pointer instead of int (default) which was causing problems on 64 bit systems. Use truncating division operator to support python 3. --- python/riffa.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/riffa.py b/python/riffa.py index 1213677..94c76aa 100644 --- a/python/riffa.py +++ b/python/riffa.py @@ -1,5 +1,5 @@ # ---------------------------------------------------------------------- -# Copyright (c) 2016, The Regents of the University of California All +# Copyright (c) 2015, The Regents of the University of California All # rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -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 From 718d167823a07b4cab903127c88db8888052dab8 Mon Sep 17 00:00:00 2001 From: Jonathan O'Brien Date: Mon, 28 Mar 2016 11:09:18 -0700 Subject: [PATCH 2/8] Manually fixed up copyright date. --- python/riffa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/riffa.py b/python/riffa.py index 94c76aa..565cb6d 100644 --- a/python/riffa.py +++ b/python/riffa.py @@ -1,5 +1,5 @@ # ---------------------------------------------------------------------- -# Copyright (c) 2015, The Regents of the University of California All +# Copyright (c) 2016, The Regents of the University of California All # rights reserved. # # Redistribution and use in source and binary forms, with or without From 4e898fcf351f561367b63e26111ab9cb73e0451b Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Wed, 29 Jun 2016 14:43:38 -0700 Subject: [PATCH 3/8] Fixing unsigned windows driver issue Issue was invalid path in makefile.inc that allowed the build script to "pass" but fail to sign the RIFFA catalog file and driver (!). This issue has been fixed, and more comments have been added to the README to avoid this issue in the future. --- driver/windows/README.txt | 16 +++++++++++++--- driver/windows/install/install.bat | 17 +++++++++++++---- driver/windows/install/win7.iss | 2 +- driver/windows/sys/makefile.inc | 4 ++-- 4 files changed, 29 insertions(+), 10 deletions(-) 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 From cd494e1ea5fe6642ad4eb47be76ad153b206e6e5 Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Wed, 29 Jun 2016 14:53:47 -0700 Subject: [PATCH 4/8] Adding linux/slab.h to riffa_driver.c, which fixes a driver compilation problem on some ARM platforms. --- driver/linux/riffa_driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/driver/linux/riffa_driver.c b/driver/linux/riffa_driver.c index a50b70c..c160485 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" From 57e389ef81146610eab2ea7759d3383efc11c776 Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Wed, 29 Jun 2016 15:42:05 -0700 Subject: [PATCH 5/8] Fixing some capability problems in the linux driver. Fixing register define #ifdef macros, because I thought they looked ugly Implementing method bodies instead of empty methods, because I really would like that functionality, even if it is for the purpose of debate. --- driver/linux/riffa_driver.c | 107 ++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 28 deletions(-) diff --git a/driver/linux/riffa_driver.c b/driver/linux/riffa_driver.c index c160485..39775b5 100644 --- a/driver/linux/riffa_driver.c +++ b/driver/linux/riffa_driver.c @@ -157,55 +157,106 @@ 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. + * 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 verbatim 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 -#ifndef PCI_EXP_DEVCTL2_IDO_REQ_EN -#define PCI_EXP_DEVCTL2_IDO_REQ_EN 0 -#endif -#ifndef PCI_EXP_DEVCTL2_IDO_CMP_EN -#define PCI_EXP_DEVCTL2_IDO_CMP_EN 0 -#endif -#ifndef PCI_EXP_DEVCTL -#define PCI_EXP_DEVCTL 0 -#endif -#ifndef PCI_EXP_LNKCTL_RCB -#define PCI_EXP_LNKCTL_RCB 0 +#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 +#define PCI_EXP_DEVCTL2_IDO_REQ_EN PCI_EXP_IDO_REQ_EN +#define PCI_EXP_DEVCTL2_IDO_CMP_EN PCI_EXP_IDO_CMP_EN #endif int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) { + int ret; + + *val = 0; + if (pos & 1) + return -EINVAL; + + if (pcie_capability_reg_implemented(dev, pos)) { + 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; + } + + /* + * For Functions that do not implement the Slot Capabilities, + * Slot Status, and Slot Control registers, these spaces must + * be hardwired to 0b, with the exception of the Presence Detect + * State bit in the Slot Status register of Downstream Ports, + * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) + */ + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + return 0; } int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) { + int ret; + + *val = 0; + if (pos & 3) + return -EINVAL; + + if (pcie_capability_reg_implemented(dev, pos)) { + 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; + } + + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + return 0; } int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) { - return 0; + if (pos & 1) + return -EINVAL; + + if (!pcie_capability_reg_implemented(dev, pos)) + return 0; + + 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; + + if (!pcie_capability_reg_implemented(dev, pos)) + return 0; + + return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); } #endif From 64cd40f0b69bd75a6c269bdf80b9607771b1d2dc Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Wed, 29 Jun 2016 15:59:23 -0700 Subject: [PATCH 6/8] Fixing the missing registers for real (I misread the problem) --- driver/linux/riffa_driver.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/driver/linux/riffa_driver.c b/driver/linux/riffa_driver.c index 39775b5..a14cee1 100644 --- a/driver/linux/riffa_driver.c +++ b/driver/linux/riffa_driver.c @@ -158,6 +158,24 @@ unsigned long long __udivdi3(unsigned long long num, unsigned long long den) #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 PCI_EXP_IDO_REQ_EN +#endif +#ifndef PCI_EXP_DEVCTL2_IDO_CMP_EN +#define PCI_EXP_DEVCTL2_IDO_CMP_EN PCI_EXP_IDO_CMP_EN +#endif +#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,11) /** @@ -166,13 +184,6 @@ unsigned long long __udivdi3(unsigned long long num, unsigned long long den) * easier to copy the declarations verbatim here than a bunch of conditionals * everywhere else. */ -#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 -#define PCI_EXP_DEVCTL2_IDO_REQ_EN PCI_EXP_IDO_REQ_EN -#define PCI_EXP_DEVCTL2_IDO_CMP_EN PCI_EXP_IDO_CMP_EN -#endif int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) { @@ -260,6 +271,9 @@ int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) } #endif + + + /////////////////////////////////////////////////////// // INTERRUPT HANDLER /////////////////////////////////////////////////////// From 1d228c190dbeeb0001d472000c5fb142ef9d414a Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Wed, 29 Jun 2016 16:39:16 -0700 Subject: [PATCH 7/8] Fixing more backwards compatibility issues Had to remove some method calls --- driver/linux/riffa_driver.c | 64 ++++++++++--------------------------- 1 file changed, 17 insertions(+), 47 deletions(-) diff --git a/driver/linux/riffa_driver.c b/driver/linux/riffa_driver.c index a14cee1..5bde56e 100644 --- a/driver/linux/riffa_driver.c +++ b/driver/linux/riffa_driver.c @@ -181,7 +181,7 @@ unsigned long long __udivdi3(unsigned long long num, unsigned long long den) /** * 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 verbatim here than a bunch of conditionals + * easier to copy the declarations (not verbatim) here than a bunch of conditionals * everywhere else. */ @@ -193,31 +193,15 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) if (pos & 1) return -EINVAL; - if (pcie_capability_reg_implemented(dev, pos)) { - 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; - } - + ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); /* - * For Functions that do not implement the Slot Capabilities, - * Slot Status, and Slot Control registers, these spaces must - * be hardwired to 0b, with the exception of the Presence Detect - * State bit in the Slot Status register of Downstream Ports, - * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) + * 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 (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && - pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { - *val = PCI_EXP_SLTSTA_PDS; - } - - return 0; + if (ret) + *val = 0; + return ret; } int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) @@ -228,24 +212,16 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) if (pos & 3) return -EINVAL; - if (pcie_capability_reg_implemented(dev, pos)) { - 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; - } + 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; - if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && - pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { - *val = PCI_EXP_SLTSTA_PDS; - } - - return 0; } int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) @@ -253,9 +229,6 @@ int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) if (pos & 1) return -EINVAL; - if (!pcie_capability_reg_implemented(dev, pos)) - return 0; - return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); } @@ -264,9 +237,6 @@ int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) if (pos & 3) return -EINVAL; - if (!pcie_capability_reg_implemented(dev, pos)) - return 0; - return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); } #endif From 778c42e74b23f542e7523f99e6f13558dd3fbfef Mon Sep 17 00:00:00 2001 From: Dustin Richmond Date: Mon, 18 Jul 2016 16:28:11 -0700 Subject: [PATCH 8/8] First attempt (and maybe only) at fixing a bug in the CHNL_TX interface. In the interface, CHNL_TX_DATA_REN was remaining asserted for two cycles after CHNL_TX was deasserted. This has been fixed, and CHNL_TX_DATA_REN now deasserts one cycle after CHNL_TX is deasserted. --- fpga/riffa_hdl/tx_port_channel_gate_128.v | 308 ++++++++++----------- fpga/riffa_hdl/tx_port_channel_gate_32.v | 311 ++++++++++------------ fpga/riffa_hdl/tx_port_channel_gate_64.v | 308 ++++++++++----------- 3 files changed, 434 insertions(+), 493 deletions(-) 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