1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-30 08:32:52 +08:00

Register space reorganization

This commit is contained in:
Alex Forencich 2021-12-29 22:31:46 -08:00
parent 6163efa0b8
commit ce21774f06
150 changed files with 6128 additions and 2466 deletions

View File

@ -379,7 +379,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
for interface in tb.driver.interfaces: for interface in tb.driver.interfaces:
await interface.ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await interface.ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(interface.tx_queue_count): for k in range(interface.tx_queue_count):
await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -513,7 +513,7 @@ async def run_test_nic(dut):
tb.log.info("All interface 0 ports") tb.log.info("All interface 0 ports")
for port in tb.driver.interfaces[0].ports: for port in tb.driver.interfaces[0].ports:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(port.interface.tx_queue_count): for k in range(port.interface.tx_queue_count):
if k % len(tb.driver.interfaces[0].ports) == port.index: if k % len(tb.driver.interfaces[0].ports) == port.index:
await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -539,7 +539,7 @@ async def run_test_nic(dut):
tb.loopback_enable = False tb.loopback_enable = False
for port in tb.driver.interfaces[0].ports[1:]: for port in tb.driver.interfaces[0].ports[1:]:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000000) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000)
tb.log.info("Read statistics counters") tb.log.info("Read statistics counters")

View File

@ -43,10 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module mqnic_core # module mqnic_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0, parameter FPGA_ID = 32'hDEADBEEF,
parameter FW_VER = {16'd0, 16'd1}, parameter FW_ID = 32'h00000000,
parameter BOARD_ID = {16'h1234, 16'h0000}, parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_VER = {16'd0, 16'd1}, parameter BOARD_ID = 16'h1234_0000,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -140,6 +144,7 @@ module mqnic_core #
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT), parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT),
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8), parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8),
parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0, parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0,
parameter RB_NEXT_PTR = 0,
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
@ -378,6 +383,16 @@ parameter AXIS_IF_KEEP_WIDTH = AXIS_SYNC_KEEP_WIDTH;
parameter AXIS_IF_TX_USER_WIDTH = AXIS_TX_USER_WIDTH; parameter AXIS_IF_TX_USER_WIDTH = AXIS_TX_USER_WIDTH;
parameter AXIS_IF_RX_USER_WIDTH = AXIS_RX_USER_WIDTH; parameter AXIS_IF_RX_USER_WIDTH = AXIS_RX_USER_WIDTH;
localparam PHC_RB_BASE_ADDR = 32'h100;
// check configuration
initial begin
if (RB_NEXT_PTR > 0 && RB_NEXT_PTR < 16'h200) begin
$error("Error: RB_NEXT_PTR overlaps block (instance %m)");
$finish;
end
end
// parameter sizing helpers // parameter sizing helpers
function [31:0] w_32(input [31:0] val); function [31:0] w_32(input [31:0] val);
w_32 = val; w_32 = val;
@ -533,16 +548,34 @@ always @(posedge clk) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
8'h00: ctrl_reg_rd_data_reg <= FW_ID; // fw_id // FW ID
8'h04: ctrl_reg_rd_data_reg <= FW_VER; // fw_ver 8'h00: ctrl_reg_rd_data_reg <= 32'hffffffff; // FW ID: Type
8'h08: ctrl_reg_rd_data_reg <= BOARD_ID; // board_id 8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // FW ID: Version
8'h0C: ctrl_reg_rd_data_reg <= BOARD_VER; // board_ver 8'h08: ctrl_reg_rd_data_reg <= 32'h40; // FW ID: Next header
8'h10: ctrl_reg_rd_data_reg <= 1; // phc_count 8'h0C: ctrl_reg_rd_data_reg <= FPGA_ID; // FW ID: FPGA JTAG ID
8'h14: ctrl_reg_rd_data_reg <= 16'h0200; // phc_offset 8'h10: ctrl_reg_rd_data_reg <= FW_ID; // FW ID: Firmware ID
8'h18: ctrl_reg_rd_data_reg <= 16'h0080; // phc_stride 8'h14: ctrl_reg_rd_data_reg <= FW_VER; // FW ID: Firmware version
8'h20: ctrl_reg_rd_data_reg <= IF_COUNT; // if_count 8'h18: ctrl_reg_rd_data_reg <= BOARD_ID; // FW ID: Board ID
8'h24: ctrl_reg_rd_data_reg <= 2**AXIL_IF_CTRL_ADDR_WIDTH; // if_stride 8'h1C: ctrl_reg_rd_data_reg <= BOARD_VER; // FW ID: Board version
8'h2C: ctrl_reg_rd_data_reg <= 2**AXIL_CSR_ADDR_WIDTH; // if_csr_offset 8'h20: ctrl_reg_rd_data_reg <= BUILD_DATE; // FW ID: Build date
8'h24: ctrl_reg_rd_data_reg <= GIT_HASH; // FW ID: Git commit hash
8'h28: ctrl_reg_rd_data_reg <= RELEASE_INFO; // FW ID: Release info
// Interface
8'h40: ctrl_reg_rd_data_reg <= 32'h0000C000; // Interface: Type
8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // Interface: Version
8'h48: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 32'h60 : PHC_RB_BASE_ADDR; // Interface: Next header
8'h4C: ctrl_reg_rd_data_reg <= 32'h0; // Interface: Offset
8'h50: ctrl_reg_rd_data_reg <= IF_COUNT; // Interface: Count
8'h54: ctrl_reg_rd_data_reg <= 2**AXIL_IF_CTRL_ADDR_WIDTH; // Interface: Stride
8'h58: ctrl_reg_rd_data_reg <= 2**AXIL_CSR_ADDR_WIDTH; // Interface: CSR offset
// Stats
8'h60: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 32'h0000C004 : 0; // Stats: Type
8'h64: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 32'h00000100 : 0; // Stats: Version
8'h68: ctrl_reg_rd_data_reg <= STAT_ENABLE ? PHC_RB_BASE_ADDR : 0; // Stats: Next header
8'h6C: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 2**16 : 0; // Stats: Offset
8'h70: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 2**STAT_ID_WIDTH : 0; // Stats: Count
8'h74: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 8 : 0; // Stats: Stride
8'h78: ctrl_reg_rd_data_reg <= STAT_ENABLE ? 32'h00000000 : 0; // Stats: Flags
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -561,9 +594,11 @@ mqnic_ptp #(
.PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE),
.PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT),
.REG_ADDR_WIDTH(8), .REG_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH),
.REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), .REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH),
.REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH) .REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH),
.RB_BASE_ADDR(PHC_RB_BASE_ADDR),
.RB_NEXT_PTR(RB_NEXT_PTR)
) )
mqnic_ptp_inst ( mqnic_ptp_inst (
.clk(clk), .clk(clk),
@ -575,11 +610,11 @@ mqnic_ptp_inst (
.reg_wr_addr(ctrl_reg_wr_addr), .reg_wr_addr(ctrl_reg_wr_addr),
.reg_wr_data(ctrl_reg_wr_data), .reg_wr_data(ctrl_reg_wr_data),
.reg_wr_strb(ctrl_reg_wr_strb), .reg_wr_strb(ctrl_reg_wr_strb),
.reg_wr_en(ctrl_reg_wr_en && (ctrl_reg_wr_addr >> 8 == 2)), .reg_wr_en(ctrl_reg_wr_en),
.reg_wr_wait(ptp_ctrl_reg_wr_wait), .reg_wr_wait(ptp_ctrl_reg_wr_wait),
.reg_wr_ack(ptp_ctrl_reg_wr_ack), .reg_wr_ack(ptp_ctrl_reg_wr_ack),
.reg_rd_addr(ctrl_reg_rd_addr), .reg_rd_addr(ctrl_reg_rd_addr),
.reg_rd_en(ctrl_reg_rd_en && (ctrl_reg_rd_addr >> 8 == 2)), .reg_rd_en(ctrl_reg_rd_en),
.reg_rd_data(ptp_ctrl_reg_rd_data), .reg_rd_data(ptp_ctrl_reg_rd_data),
.reg_rd_wait(ptp_ctrl_reg_rd_wait), .reg_rd_wait(ptp_ctrl_reg_rd_wait),
.reg_rd_ack(ptp_ctrl_reg_rd_ack), .reg_rd_ack(ptp_ctrl_reg_rd_ack),

View File

@ -43,10 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module mqnic_core_axi # module mqnic_core_axi #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0, parameter FPGA_ID = 32'hDEADBEEF,
parameter FW_VER = {16'd0, 16'd1}, parameter FW_ID = 32'h00000000,
parameter BOARD_ID = {16'h1234, 16'h0000}, parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_VER = {16'd0, 16'd1}, parameter BOARD_ID = 16'h1234_0000,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -143,6 +147,7 @@ module mqnic_core_axi #
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT), parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT),
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8), parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8),
parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0, parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0,
parameter RB_NEXT_PTR = 0,
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
@ -534,10 +539,14 @@ dma_if_axi_inst (
mqnic_core #( mqnic_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -631,6 +640,7 @@ mqnic_core #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE), .AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE),
.RB_NEXT_PTR(RB_NEXT_PTR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -43,10 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module mqnic_core_pcie # module mqnic_core_pcie #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0, parameter FPGA_ID = 32'hDEADBEEF,
parameter FW_VER = {16'd0, 16'd1}, parameter FW_ID = 32'h00000000,
parameter BOARD_ID = {16'h1234, 16'h0000}, parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_VER = {16'd0, 16'd1}, parameter BOARD_ID = 16'h1234_0000,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -152,6 +156,7 @@ module mqnic_core_pcie #
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT), parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT),
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8), parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8),
parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0, parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0,
parameter RB_NEXT_PTR = 0,
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
@ -1290,10 +1295,14 @@ endgenerate
mqnic_core #( mqnic_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1387,6 +1396,7 @@ mqnic_core #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE), .AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE),
.RB_NEXT_PTR(RB_NEXT_PTR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -43,10 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module mqnic_core_pcie_s10 # module mqnic_core_pcie_s10 #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0, parameter FPGA_ID = 32'hDEADBEEF,
parameter FW_VER = {16'd0, 16'd1}, parameter FW_ID = 32'h00000000,
parameter BOARD_ID = {16'h1234, 16'h0000}, parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_VER = {16'd0, 16'd1}, parameter BOARD_ID = 16'h1234_0000,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -149,6 +153,7 @@ module mqnic_core_pcie_s10 #
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT), parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT),
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8), parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8),
parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0, parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0,
parameter RB_NEXT_PTR = 0,
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
@ -559,10 +564,14 @@ pcie_s10_if_inst (
mqnic_core_pcie #( mqnic_core_pcie #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -668,6 +677,7 @@ mqnic_core_pcie #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE), .AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE),
.RB_NEXT_PTR(RB_NEXT_PTR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -43,10 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module mqnic_core_pcie_us # module mqnic_core_pcie_us #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0, parameter FPGA_ID = 32'hDEADBEEF,
parameter FW_VER = {16'd0, 16'd1}, parameter FW_ID = 32'h00000000,
parameter BOARD_ID = {16'h1234, 16'h0000}, parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_VER = {16'd0, 16'd1}, parameter BOARD_ID = 16'h1234_0000,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -150,6 +154,7 @@ module mqnic_core_pcie_us #
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT), parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT),
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8), parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8),
parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0, parameter AXIL_CSR_PASSTHROUGH_ENABLE = 0,
parameter RB_NEXT_PTR = 0,
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
@ -649,10 +654,14 @@ pcie_if_inst (
mqnic_core_pcie #( mqnic_core_pcie #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -758,6 +767,7 @@ mqnic_core_pcie #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE), .AXIL_CSR_PASSTHROUGH_ENABLE(AXIL_CSR_PASSTHROUGH_ENABLE),
.RB_NEXT_PTR(RB_NEXT_PTR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -370,6 +370,7 @@ parameter QUEUE_REQ_TAG_WIDTH = $clog2(MAX_DESC_TABLE_SIZE) + 1 + $clog2(PORTS+1
parameter QUEUE_OP_TAG_WIDTH = 6; parameter QUEUE_OP_TAG_WIDTH = 6;
parameter DMA_TAG_WIDTH_INT = DMA_TAG_WIDTH - $clog2(PORTS); parameter DMA_TAG_WIDTH_INT = DMA_TAG_WIDTH - $clog2(PORTS);
parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH;
parameter QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH > RX_QUEUE_INDEX_WIDTH ? TX_QUEUE_INDEX_WIDTH : RX_QUEUE_INDEX_WIDTH; parameter QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH > RX_QUEUE_INDEX_WIDTH ? TX_QUEUE_INDEX_WIDTH : RX_QUEUE_INDEX_WIDTH;
parameter CPL_QUEUE_INDEX_WIDTH = TX_CPL_QUEUE_INDEX_WIDTH > RX_CPL_QUEUE_INDEX_WIDTH ? TX_CPL_QUEUE_INDEX_WIDTH : RX_CPL_QUEUE_INDEX_WIDTH; parameter CPL_QUEUE_INDEX_WIDTH = TX_CPL_QUEUE_INDEX_WIDTH > RX_CPL_QUEUE_INDEX_WIDTH ? TX_CPL_QUEUE_INDEX_WIDTH : RX_CPL_QUEUE_INDEX_WIDTH;
@ -394,7 +395,11 @@ parameter AXIL_RX_QM_BASE_ADDR = AXIL_TX_CQM_BASE_ADDR + 2**AXIL_TX_CQM_ADDR_WID
parameter AXIL_RX_CQM_BASE_ADDR = AXIL_RX_QM_BASE_ADDR + 2**AXIL_RX_QM_ADDR_WIDTH; parameter AXIL_RX_CQM_BASE_ADDR = AXIL_RX_QM_BASE_ADDR + 2**AXIL_RX_QM_ADDR_WIDTH;
parameter AXIL_PORT_BASE_ADDR = AXIL_RX_CQM_BASE_ADDR + 2**AXIL_RX_CQM_ADDR_WIDTH; parameter AXIL_PORT_BASE_ADDR = AXIL_RX_CQM_BASE_ADDR + 2**AXIL_RX_CQM_ADDR_WIDTH;
parameter PORT_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(PORTS+1); localparam RB_BASE_ADDR = AXIL_CTRL_BASE_ADDR;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
localparam PORT_RB_BASE_ADDR = RB_BASE_ADDR + 16'h1000;
localparam PORT_RB_STRIDE = 16'h1000;
// parameter sizing helpers // parameter sizing helpers
function [31:0] w_32(input [31:0] val); function [31:0] w_32(input [31:0] val);
@ -903,6 +908,11 @@ always @* begin
end end
end end
reg [DMA_CLIENT_LEN_WIDTH-1:0] tx_mtu_reg = MAX_TX_SIZE;
reg [DMA_CLIENT_LEN_WIDTH-1:0] rx_mtu_reg = MAX_RX_SIZE;
reg [RX_QUEUE_INDEX_WIDTH-1:0] rss_mask_reg = 0;
always @(posedge clk) begin always @(posedge clk) begin
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
ctrl_reg_rd_data_reg <= {AXIL_DATA_WIDTH{1'b0}}; ctrl_reg_rd_data_reg <= {AXIL_DATA_WIDTH{1'b0}};
@ -910,38 +920,81 @@ always @(posedge clk) begin
if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b1;
// case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
// default: ctrl_reg_wr_ack_reg <= 1'b0; // Interface control (TX)
// endcase RBB+8'h14: tx_mtu_reg <= ctrl_reg_wr_data; // IF TX ctrl: TX MTU
// Interface control (RX)
RBB+8'h34: rx_mtu_reg <= ctrl_reg_wr_data; // IF RX ctrl: RX MTU
RBB+8'h38: rss_mask_reg <= ctrl_reg_wr_data; // IF RX ctrl: RSS mask
default: ctrl_reg_wr_ack_reg <= 1'b0;
endcase
end end
if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0000: ctrl_reg_rd_data_reg <= 32'd0; // if_id // Interface control (TX)
16'h0004: begin RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C001; // IF TX ctrl: Type
// if_features RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // IF TX ctrl: Version
ctrl_reg_rd_data_reg[0] <= RX_RSS_ENABLE && RX_HASH_ENABLE; RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // IF TX ctrl: Next header
RBB+8'h0C: begin
// IF TX ctrl: features
ctrl_reg_rd_data_reg[4] <= PTP_TS_ENABLE; ctrl_reg_rd_data_reg[4] <= PTP_TS_ENABLE;
ctrl_reg_rd_data_reg[8] <= TX_CHECKSUM_ENABLE; ctrl_reg_rd_data_reg[8] <= TX_CHECKSUM_ENABLE;
ctrl_reg_rd_data_reg[9] <= RX_CHECKSUM_ENABLE;
ctrl_reg_rd_data_reg[10] <= RX_HASH_ENABLE;
end end
16'h0010: ctrl_reg_rd_data_reg <= 2**EVENT_QUEUE_INDEX_WIDTH; // event_queue_count RBB+8'h10: ctrl_reg_rd_data_reg <= MAX_TX_SIZE; // IF TX ctrl: Max TX MTU
16'h0014: ctrl_reg_rd_data_reg <= AXIL_EQM_BASE_ADDR; // event_queue_offset RBB+8'h14: ctrl_reg_rd_data_reg <= tx_mtu_reg; // IF TX ctrl: TX MTU
16'h0020: ctrl_reg_rd_data_reg <= 2**TX_QUEUE_INDEX_WIDTH; // tx_queue_count // Interface control (RX)
16'h0024: ctrl_reg_rd_data_reg <= AXIL_TX_QM_BASE_ADDR; // tx_queue_offset RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C002; // IF RX ctrl: Type
16'h0028: ctrl_reg_rd_data_reg <= 2**TX_CPL_QUEUE_INDEX_WIDTH; // tx_cpl_queue_count RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // IF RX ctrl: Version
16'h002C: ctrl_reg_rd_data_reg <= AXIL_TX_CQM_BASE_ADDR; // tx_cpl_queue_offset RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // IF RX ctrl: Next header
16'h0030: ctrl_reg_rd_data_reg <= 2**RX_QUEUE_INDEX_WIDTH; // rx_queue_count RBB+8'h2C: begin
16'h0034: ctrl_reg_rd_data_reg <= AXIL_RX_QM_BASE_ADDR; // rx_queue_offset // IF RX ctrl: features
16'h0038: ctrl_reg_rd_data_reg <= 2**RX_CPL_QUEUE_INDEX_WIDTH; // rx_cpl_queue_count ctrl_reg_rd_data_reg[0] <= RX_RSS_ENABLE && RX_HASH_ENABLE;
16'h003C: ctrl_reg_rd_data_reg <= AXIL_RX_CQM_BASE_ADDR; // rx_cpl_queue_offset ctrl_reg_rd_data_reg[4] <= PTP_TS_ENABLE;
16'h0040: ctrl_reg_rd_data_reg <= PORTS; // port_count ctrl_reg_rd_data_reg[8] <= RX_CHECKSUM_ENABLE;
16'h0044: ctrl_reg_rd_data_reg <= AXIL_CTRL_BASE_ADDR + 2**PORT_CTRL_ADDR_WIDTH; // port_offset ctrl_reg_rd_data_reg[9] <= RX_HASH_ENABLE;
16'h0048: ctrl_reg_rd_data_reg <= 2**PORT_CTRL_ADDR_WIDTH; // port_stride end
RBB+8'h30: ctrl_reg_rd_data_reg <= MAX_RX_SIZE; // IF RX ctrl: Max RX MTU
RBB+8'h34: ctrl_reg_rd_data_reg <= rx_mtu_reg; // IF RX ctrl: RX MTU
RBB+8'h38: ctrl_reg_rd_data_reg <= rss_mask_reg; // IF RX ctrl: RSS mask
// Queue manager (Event)
RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C010; // Event QM: Type
RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // Event QM: Version
RBB+8'h48: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h60; // Event QM: Next header
RBB+8'h4C: ctrl_reg_rd_data_reg <= AXIL_EQM_BASE_ADDR; // Event QM: Offset
RBB+8'h50: ctrl_reg_rd_data_reg <= 2**EVENT_QUEUE_INDEX_WIDTH; // Event QM: Count
RBB+8'h54: ctrl_reg_rd_data_reg <= 32; // Event QM: Stride
// Queue manager (TX)
RBB+8'h60: ctrl_reg_rd_data_reg <= 32'h0000C020; // TX QM: Type
RBB+8'h64: ctrl_reg_rd_data_reg <= 32'h00000100; // TX QM: Version
RBB+8'h68: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h80; // TX QM: Next header
RBB+8'h6C: ctrl_reg_rd_data_reg <= AXIL_TX_QM_BASE_ADDR; // TX QM: Offset
RBB+8'h70: ctrl_reg_rd_data_reg <= 2**TX_QUEUE_INDEX_WIDTH; // TX QM: Count
RBB+8'h74: ctrl_reg_rd_data_reg <= 32; // TX QM: Stride
// Queue manager (TX CPL)
RBB+8'h80: ctrl_reg_rd_data_reg <= 32'h0000C030; // TX CPL QM: Type
RBB+8'h84: ctrl_reg_rd_data_reg <= 32'h00000100; // TX CPL QM: Version
RBB+8'h88: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'hA0; // TX CPL QM: Next header
RBB+8'h8C: ctrl_reg_rd_data_reg <= AXIL_TX_CQM_BASE_ADDR; // TX CPL QM: Offset
RBB+8'h90: ctrl_reg_rd_data_reg <= 2**TX_CPL_QUEUE_INDEX_WIDTH; // TX CPL QM: Count
RBB+8'h94: ctrl_reg_rd_data_reg <= 32; // TX CPL QM: Stride
// Queue manager (RX)
RBB+8'hA0: ctrl_reg_rd_data_reg <= 32'h0000C021; // RX QM: Type
RBB+8'hA4: ctrl_reg_rd_data_reg <= 32'h00000100; // RX QM: Version
RBB+8'hA8: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'hC0; // RX QM: Next header
RBB+8'hAC: ctrl_reg_rd_data_reg <= AXIL_RX_QM_BASE_ADDR; // RX QM: Offset
RBB+8'hB0: ctrl_reg_rd_data_reg <= 2**RX_QUEUE_INDEX_WIDTH; // RX QM: Count
RBB+8'hB4: ctrl_reg_rd_data_reg <= 32; // RX QM: Stride
// Queue manager (RX CPL)
RBB+8'hC0: ctrl_reg_rd_data_reg <= 32'h0000C031; // RX CPL QM: Type
RBB+8'hC4: ctrl_reg_rd_data_reg <= 32'h00000100; // RX CPL QM: Version
RBB+8'hC8: ctrl_reg_rd_data_reg <= PORT_RB_BASE_ADDR; // RX CPL QM: Next header
RBB+8'hCC: ctrl_reg_rd_data_reg <= AXIL_RX_CQM_BASE_ADDR; // RX CPL QM: Offset
RBB+8'hD0: ctrl_reg_rd_data_reg <= 2**RX_CPL_QUEUE_INDEX_WIDTH; // RX CPL QM: Count
RBB+8'hD4: ctrl_reg_rd_data_reg <= 32; // RX CPL QM: Stride
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -949,6 +1002,11 @@ always @(posedge clk) begin
if (rst) begin if (rst) begin
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
ctrl_reg_rd_ack_reg <= 1'b0; ctrl_reg_rd_ack_reg <= 1'b0;
tx_mtu_reg <= MAX_TX_SIZE;
rx_mtu_reg <= MAX_RX_SIZE;
rss_mask_reg <= 0;
end end
end end
@ -2120,6 +2178,7 @@ generate
mqnic_port #( mqnic_port #(
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH), .DMA_ADDR_WIDTH(DMA_ADDR_WIDTH),
.DMA_LEN_WIDTH(DMA_LEN_WIDTH), .DMA_LEN_WIDTH(DMA_LEN_WIDTH),
.DMA_CLIENT_LEN_WIDTH(DMA_CLIENT_LEN_WIDTH),
.DMA_TAG_WIDTH(DMA_TAG_WIDTH_INT), .DMA_TAG_WIDTH(DMA_TAG_WIDTH_INT),
.REQ_TAG_WIDTH(REQ_TAG_WIDTH), .REQ_TAG_WIDTH(REQ_TAG_WIDTH),
.DESC_REQ_TAG_WIDTH(PORT_DESC_REQ_TAG_WIDTH), .DESC_REQ_TAG_WIDTH(PORT_DESC_REQ_TAG_WIDTH),
@ -2149,12 +2208,14 @@ generate
.RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE),
.RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE),
.REG_DATA_WIDTH(AXIL_DATA_WIDTH), .REG_DATA_WIDTH(AXIL_DATA_WIDTH),
.REG_ADDR_WIDTH(PORT_CTRL_ADDR_WIDTH), .REG_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH),
.REG_STRB_WIDTH(AXIL_STRB_WIDTH), .REG_STRB_WIDTH(AXIL_STRB_WIDTH),
.RB_BASE_ADDR(PORT_RB_BASE_ADDR + PORT_RB_STRIDE*n),
.RB_NEXT_PTR(n < PORTS-1 ? PORT_RB_BASE_ADDR + PORT_RB_STRIDE*(n+1) : 0),
.AXIL_DATA_WIDTH(AXIL_DATA_WIDTH), .AXIL_DATA_WIDTH(AXIL_DATA_WIDTH),
.AXIL_ADDR_WIDTH(AXIL_PORT_ADDR_WIDTH), .AXIL_ADDR_WIDTH(AXIL_PORT_ADDR_WIDTH),
.AXIL_STRB_WIDTH(AXIL_STRB_WIDTH), .AXIL_STRB_WIDTH(AXIL_STRB_WIDTH),
.AXIL_OFFSET(AXIL_PORT_BASE_ADDR + (2**AXIL_PORT_ADDR_WIDTH)*n - (AXIL_CTRL_BASE_ADDR + (2**PORT_CTRL_ADDR_WIDTH)*(n+1))), .AXIL_OFFSET(AXIL_PORT_BASE_ADDR + (2**AXIL_PORT_ADDR_WIDTH)*n),
.SEG_COUNT(SEG_COUNT), .SEG_COUNT(SEG_COUNT),
.SEG_DATA_WIDTH(SEG_DATA_WIDTH), .SEG_DATA_WIDTH(SEG_DATA_WIDTH),
.SEG_ADDR_WIDTH(SEG_ADDR_WIDTH), .SEG_ADDR_WIDTH(SEG_ADDR_WIDTH),
@ -2271,11 +2332,11 @@ generate
.ctrl_reg_wr_addr(ctrl_reg_wr_addr), .ctrl_reg_wr_addr(ctrl_reg_wr_addr),
.ctrl_reg_wr_data(ctrl_reg_wr_data), .ctrl_reg_wr_data(ctrl_reg_wr_data),
.ctrl_reg_wr_strb(ctrl_reg_wr_strb), .ctrl_reg_wr_strb(ctrl_reg_wr_strb),
.ctrl_reg_wr_en(ctrl_reg_wr_en && ((ctrl_reg_wr_addr >> PORT_CTRL_ADDR_WIDTH) == n+1)), .ctrl_reg_wr_en(ctrl_reg_wr_en),
.ctrl_reg_wr_wait(port_ctrl_reg_wr_wait[n]), .ctrl_reg_wr_wait(port_ctrl_reg_wr_wait[n]),
.ctrl_reg_wr_ack(port_ctrl_reg_wr_ack[n]), .ctrl_reg_wr_ack(port_ctrl_reg_wr_ack[n]),
.ctrl_reg_rd_addr(ctrl_reg_rd_addr), .ctrl_reg_rd_addr(ctrl_reg_rd_addr),
.ctrl_reg_rd_en(ctrl_reg_rd_en && ((ctrl_reg_rd_addr >> PORT_CTRL_ADDR_WIDTH) == n+1)), .ctrl_reg_rd_en(ctrl_reg_rd_en),
.ctrl_reg_rd_data(port_ctrl_reg_rd_data[n]), .ctrl_reg_rd_data(port_ctrl_reg_rd_data[n]),
.ctrl_reg_rd_wait(port_ctrl_reg_rd_wait[n]), .ctrl_reg_rd_wait(port_ctrl_reg_rd_wait[n]),
.ctrl_reg_rd_ack(port_ctrl_reg_rd_ack[n]), .ctrl_reg_rd_ack(port_ctrl_reg_rd_ack[n]),
@ -2357,7 +2418,14 @@ generate
* PTP clock * PTP clock
*/ */
.ptp_ts_96(ptp_ts_96), .ptp_ts_96(ptp_ts_96),
.ptp_ts_step(ptp_ts_step) .ptp_ts_step(ptp_ts_step),
/*
* Configuration
*/
.tx_mtu(tx_mtu_reg),
.rx_mtu(rx_mtu_reg),
.rss_mask(rss_mask_reg)
); );
end end

View File

@ -46,6 +46,8 @@ module mqnic_port #
parameter DMA_ADDR_WIDTH = 64, parameter DMA_ADDR_WIDTH = 64,
// DMA length field width // DMA length field width
parameter DMA_LEN_WIDTH = 16, parameter DMA_LEN_WIDTH = 16,
// DMA client length field width
parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH,
// DMA tag field width // DMA tag field width
parameter DMA_TAG_WIDTH = 8, parameter DMA_TAG_WIDTH = 8,
// Request tag field width // Request tag field width
@ -108,6 +110,10 @@ module mqnic_port #
parameter REG_DATA_WIDTH = 32, parameter REG_DATA_WIDTH = 32,
// Width of control register interface strb // Width of control register interface strb
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8), parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
// Register block base address
parameter RB_BASE_ADDR = 0,
// Register block next pointer
parameter RB_NEXT_PTR = 0,
// Width of AXI lite data bus in bits // Width of AXI lite data bus in bits
parameter AXIL_DATA_WIDTH = 32, parameter AXIL_DATA_WIDTH = 32,
// Width of AXI lite address bus in bits // Width of AXI lite address bus in bits
@ -334,11 +340,17 @@ module mqnic_port #
* PTP clock * PTP clock
*/ */
input wire [PTP_TS_WIDTH-1:0] ptp_ts_96, input wire [PTP_TS_WIDTH-1:0] ptp_ts_96,
input wire ptp_ts_step input wire ptp_ts_step,
/*
* Configuration
*/
input wire [DMA_CLIENT_LEN_WIDTH-1:0] tx_mtu,
input wire [DMA_CLIENT_LEN_WIDTH-1:0] rx_mtu,
input wire [RX_QUEUE_INDEX_WIDTH-1:0] rss_mask
); );
parameter DMA_CLIENT_TAG_WIDTH = $clog2(TX_DESC_TABLE_SIZE > RX_DESC_TABLE_SIZE ? TX_DESC_TABLE_SIZE : RX_DESC_TABLE_SIZE); parameter DMA_CLIENT_TAG_WIDTH = $clog2(TX_DESC_TABLE_SIZE > RX_DESC_TABLE_SIZE ? TX_DESC_TABLE_SIZE : RX_DESC_TABLE_SIZE);
parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH;
parameter DESC_REQ_TAG_WIDTH_INT = DESC_REQ_TAG_WIDTH - $clog2(2); parameter DESC_REQ_TAG_WIDTH_INT = DESC_REQ_TAG_WIDTH - $clog2(2);
@ -530,74 +542,6 @@ wire dma_rx_desc_status_user;
wire [3:0] dma_rx_desc_status_error; wire [3:0] dma_rx_desc_status_error;
wire dma_rx_desc_status_valid; wire dma_rx_desc_status_valid;
wire sched_ctrl_reg_wr_wait;
wire sched_ctrl_reg_wr_ack;
wire [AXIL_DATA_WIDTH-1:0] sched_ctrl_reg_rd_data;
wire sched_ctrl_reg_rd_wait;
wire sched_ctrl_reg_rd_ack;
reg ctrl_reg_wr_ack_reg = 1'b0;
reg [AXIL_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = {AXIL_DATA_WIDTH{1'b0}};
reg ctrl_reg_rd_ack_reg = 1'b0;
reg [RX_QUEUE_INDEX_WIDTH-1:0] rss_mask_reg = 0;
reg [DMA_CLIENT_LEN_WIDTH-1:0] tx_mtu_reg = MAX_TX_SIZE;
reg [DMA_CLIENT_LEN_WIDTH-1:0] rx_mtu_reg = MAX_RX_SIZE;
assign ctrl_reg_wr_wait = sched_ctrl_reg_wr_wait;
assign ctrl_reg_wr_ack = ctrl_reg_wr_ack_reg | sched_ctrl_reg_wr_ack;
assign ctrl_reg_rd_data = ctrl_reg_rd_data_reg | sched_ctrl_reg_rd_data;
assign ctrl_reg_rd_wait = sched_ctrl_reg_rd_wait;
assign ctrl_reg_rd_ack = ctrl_reg_rd_ack_reg | sched_ctrl_reg_rd_ack;
always @(posedge clk) begin
ctrl_reg_wr_ack_reg <= 1'b0;
ctrl_reg_rd_data_reg <= {AXIL_DATA_WIDTH{1'b0}};
ctrl_reg_rd_ack_reg <= 1'b0;
if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin
// write operation
ctrl_reg_wr_ack_reg <= 1'b1;
case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0080: rss_mask_reg <= ctrl_reg_wr_data; // RSS mask
16'h0100: tx_mtu_reg <= ctrl_reg_wr_data; // TX MTU
16'h0200: rx_mtu_reg <= ctrl_reg_wr_data; // RX MTU
default: ctrl_reg_wr_ack_reg <= 1'b0;
endcase
end
if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin
// read operation
ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0000: ctrl_reg_rd_data_reg <= 32'd0; // port_id
16'h0004: begin
// port_features
ctrl_reg_rd_data_reg[0] <= RX_RSS_ENABLE && RX_HASH_ENABLE;
ctrl_reg_rd_data_reg[4] <= PTP_TS_ENABLE;
ctrl_reg_rd_data_reg[8] <= TX_CHECKSUM_ENABLE;
ctrl_reg_rd_data_reg[9] <= RX_CHECKSUM_ENABLE;
ctrl_reg_rd_data_reg[10] <= RX_HASH_ENABLE;
end
16'h0008: ctrl_reg_rd_data_reg <= MAX_TX_SIZE; // port_mtu
16'h0080: ctrl_reg_rd_data_reg <= rss_mask_reg; // RSS mask
16'h0100: ctrl_reg_rd_data_reg <= tx_mtu_reg; // TX MTU
16'h0200: ctrl_reg_rd_data_reg <= rx_mtu_reg; // RX MTU
default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase
end
if (rst) begin
ctrl_reg_wr_ack_reg <= 1'b0;
ctrl_reg_rd_ack_reg <= 1'b0;
rss_mask_reg <= 0;
tx_mtu_reg <= MAX_TX_SIZE;
rx_mtu_reg <= MAX_RX_SIZE;
end
end
desc_op_mux #( desc_op_mux #(
.PORTS(2), .PORTS(2),
.SELECT_WIDTH(1), .SELECT_WIDTH(1),
@ -733,6 +677,8 @@ mqnic_tx_scheduler_block #(
.REG_DATA_WIDTH(REG_DATA_WIDTH), .REG_DATA_WIDTH(REG_DATA_WIDTH),
.REG_ADDR_WIDTH(REG_ADDR_WIDTH), .REG_ADDR_WIDTH(REG_ADDR_WIDTH),
.REG_STRB_WIDTH(REG_STRB_WIDTH), .REG_STRB_WIDTH(REG_STRB_WIDTH),
.RB_BASE_ADDR(RB_BASE_ADDR),
.RB_NEXT_PTR(RB_NEXT_PTR),
.AXIL_DATA_WIDTH(AXIL_DATA_WIDTH), .AXIL_DATA_WIDTH(AXIL_DATA_WIDTH),
.AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH), .AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH),
.AXIL_STRB_WIDTH(AXIL_STRB_WIDTH), .AXIL_STRB_WIDTH(AXIL_STRB_WIDTH),
@ -757,13 +703,13 @@ scheduler_block (
.ctrl_reg_wr_data(ctrl_reg_wr_data), .ctrl_reg_wr_data(ctrl_reg_wr_data),
.ctrl_reg_wr_strb(ctrl_reg_wr_strb), .ctrl_reg_wr_strb(ctrl_reg_wr_strb),
.ctrl_reg_wr_en(ctrl_reg_wr_en), .ctrl_reg_wr_en(ctrl_reg_wr_en),
.ctrl_reg_wr_wait(sched_ctrl_reg_wr_wait), .ctrl_reg_wr_wait(ctrl_reg_wr_wait),
.ctrl_reg_wr_ack(sched_ctrl_reg_wr_ack), .ctrl_reg_wr_ack(ctrl_reg_wr_ack),
.ctrl_reg_rd_addr(ctrl_reg_rd_addr), .ctrl_reg_rd_addr(ctrl_reg_rd_addr),
.ctrl_reg_rd_en(ctrl_reg_rd_en), .ctrl_reg_rd_en(ctrl_reg_rd_en),
.ctrl_reg_rd_data(sched_ctrl_reg_rd_data), .ctrl_reg_rd_data(ctrl_reg_rd_data),
.ctrl_reg_rd_wait(sched_ctrl_reg_rd_wait), .ctrl_reg_rd_wait(ctrl_reg_rd_wait),
.ctrl_reg_rd_ack(sched_ctrl_reg_rd_ack), .ctrl_reg_rd_ack(ctrl_reg_rd_ack),
/* /*
* AXI-Lite slave interface * AXI-Lite slave interface
@ -1204,7 +1150,7 @@ rx_engine_inst (
/* /*
* Configuration * Configuration
*/ */
.mtu(rx_mtu_reg), .mtu(rx_mtu),
.enable(1'b1) .enable(1'b1)
); );
@ -1338,7 +1284,7 @@ if (RX_RSS_ENABLE && RX_HASH_ENABLE) begin
.rst(rst), .rst(rst),
// AXI input // AXI input
.s_axis_tdata(rx_hash & rss_mask_reg), .s_axis_tdata(rx_hash & rss_mask),
.s_axis_tkeep(0), .s_axis_tkeep(0),
.s_axis_tvalid(rx_hash_valid), .s_axis_tvalid(rx_hash_valid),
.s_axis_tready(), .s_axis_tready(),

View File

@ -51,7 +51,9 @@ module mqnic_ptp #
parameter PTP_PEROUT_COUNT = 1, parameter PTP_PEROUT_COUNT = 1,
parameter REG_ADDR_WIDTH = 7+(PTP_PEROUT_ENABLE ? $clog2((PTP_PEROUT_COUNT+1)/2) + 1 : 0), parameter REG_ADDR_WIDTH = 7+(PTP_PEROUT_ENABLE ? $clog2((PTP_PEROUT_COUNT+1)/2) + 1 : 0),
parameter REG_DATA_WIDTH = 32, parameter REG_DATA_WIDTH = 32,
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8) parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
parameter RB_BASE_ADDR = 0,
parameter RB_NEXT_PTR = 0
) )
( (
input wire clk, input wire clk,
@ -103,19 +105,19 @@ end
wire clock_reg_wr_wait; wire clock_reg_wr_wait;
wire clock_reg_wr_ack; wire clock_reg_wr_ack;
wire [31:0] clock_reg_rd_data; wire [REG_DATA_WIDTH-1:0] clock_reg_rd_data;
wire clock_reg_rd_wait; wire clock_reg_rd_wait;
wire clock_reg_rd_ack; wire clock_reg_rd_ack;
wire perout_reg_wr_wait[PTP_PEROUT_COUNT-1:0]; wire perout_reg_wr_wait[PTP_PEROUT_COUNT-1:0];
wire perout_reg_wr_ack[PTP_PEROUT_COUNT-1:0]; wire perout_reg_wr_ack[PTP_PEROUT_COUNT-1:0];
wire [31:0] perout_reg_rd_data[PTP_PEROUT_COUNT-1:0]; wire [REG_DATA_WIDTH-1:0] perout_reg_rd_data[PTP_PEROUT_COUNT-1:0];
wire perout_reg_rd_wait[PTP_PEROUT_COUNT-1:0]; wire perout_reg_rd_wait[PTP_PEROUT_COUNT-1:0];
wire perout_reg_rd_ack[PTP_PEROUT_COUNT-1:0]; wire perout_reg_rd_ack[PTP_PEROUT_COUNT-1:0];
reg reg_wr_wait_cmb; reg reg_wr_wait_cmb;
reg reg_wr_ack_cmb; reg reg_wr_ack_cmb;
reg [31:0] reg_rd_data_cmb; reg [REG_DATA_WIDTH-1:0] reg_rd_data_cmb;
reg reg_rd_wait_cmb; reg reg_rd_wait_cmb;
reg reg_rd_ack_cmb; reg reg_rd_ack_cmb;
@ -152,7 +154,12 @@ mqnic_ptp_clock #(
.PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE),
.PTP_PEROUT_COUNT(PTP_PEROUT_COUNT) .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT),
.REG_ADDR_WIDTH(REG_ADDR_WIDTH),
.REG_DATA_WIDTH(REG_DATA_WIDTH),
.REG_STRB_WIDTH(REG_STRB_WIDTH),
.RB_BASE_ADDR(RB_BASE_ADDR),
.RB_NEXT_PTR(PTP_PEROUT_ENABLE ? RB_BASE_ADDR + 32'h80 : RB_NEXT_PTR)
) )
ptp_clock_inst ( ptp_clock_inst (
.clk(clk), .clk(clk),
@ -164,11 +171,11 @@ ptp_clock_inst (
.reg_wr_addr(reg_wr_addr), .reg_wr_addr(reg_wr_addr),
.reg_wr_data(reg_wr_data), .reg_wr_data(reg_wr_data),
.reg_wr_strb(reg_wr_strb), .reg_wr_strb(reg_wr_strb),
.reg_wr_en(reg_wr_en && (reg_wr_addr >> 7 == 0)), .reg_wr_en(reg_wr_en),
.reg_wr_wait(clock_reg_wr_wait), .reg_wr_wait(clock_reg_wr_wait),
.reg_wr_ack(clock_reg_wr_ack), .reg_wr_ack(clock_reg_wr_ack),
.reg_rd_addr(reg_rd_addr), .reg_rd_addr(reg_rd_addr),
.reg_rd_en(reg_rd_en && (reg_rd_addr >> 7 == 0)), .reg_rd_en(reg_rd_en),
.reg_rd_data(clock_reg_rd_data), .reg_rd_data(clock_reg_rd_data),
.reg_rd_wait(clock_reg_rd_wait), .reg_rd_wait(clock_reg_rd_wait),
.reg_rd_ack(clock_reg_rd_ack), .reg_rd_ack(clock_reg_rd_ack),
@ -189,7 +196,14 @@ if (PTP_PEROUT_ENABLE) begin
for (n = 0; n < PTP_PEROUT_COUNT; n = n + 1) begin : perout for (n = 0; n < PTP_PEROUT_COUNT; n = n + 1) begin : perout
mqnic_ptp_perout ptp_perout_inst ( mqnic_ptp_perout #(
.REG_ADDR_WIDTH(REG_ADDR_WIDTH),
.REG_DATA_WIDTH(REG_DATA_WIDTH),
.REG_STRB_WIDTH(REG_STRB_WIDTH),
.RB_BASE_ADDR(RB_BASE_ADDR + 32'h80 + 32'h40*n),
.RB_NEXT_PTR(n < PTP_PEROUT_COUNT-1 ? RB_BASE_ADDR + 32'h80 + 32'h40*(n+1) : RB_NEXT_PTR)
)
ptp_perout_inst (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
@ -199,11 +213,11 @@ if (PTP_PEROUT_ENABLE) begin
.reg_wr_addr(reg_wr_addr), .reg_wr_addr(reg_wr_addr),
.reg_wr_data(reg_wr_data), .reg_wr_data(reg_wr_data),
.reg_wr_strb(reg_wr_strb), .reg_wr_strb(reg_wr_strb),
.reg_wr_en(reg_wr_en && ((reg_wr_addr >> 6) == n+2)), .reg_wr_en(reg_wr_en),
.reg_wr_wait(perout_reg_wr_wait[n]), .reg_wr_wait(perout_reg_wr_wait[n]),
.reg_wr_ack(perout_reg_wr_ack[n]), .reg_wr_ack(perout_reg_wr_ack[n]),
.reg_rd_addr(reg_rd_addr), .reg_rd_addr(reg_rd_addr),
.reg_rd_en(reg_rd_en && ((reg_rd_addr >> 6) == n+2)), .reg_rd_en(reg_rd_en),
.reg_rd_data(perout_reg_rd_data[n]), .reg_rd_data(perout_reg_rd_data[n]),
.reg_rd_wait(perout_reg_rd_wait[n]), .reg_rd_wait(perout_reg_rd_wait[n]),
.reg_rd_ack(perout_reg_rd_ack[n]), .reg_rd_ack(perout_reg_rd_ack[n]),

View File

@ -48,7 +48,12 @@ module mqnic_ptp_clock #
parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_NS = 4'd4,
parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_PERIOD_FNS = 32'd0,
parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_ENABLE = 0,
parameter PTP_PEROUT_COUNT = 1 parameter PTP_PEROUT_COUNT = 1,
parameter REG_ADDR_WIDTH = 7,
parameter REG_DATA_WIDTH = 32,
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
parameter RB_BASE_ADDR = 0,
parameter RB_NEXT_PTR = 0
) )
( (
input wire clk, input wire clk,
@ -57,15 +62,15 @@ module mqnic_ptp_clock #
/* /*
* Register interface * Register interface
*/ */
input wire [6:0] reg_wr_addr, input wire [REG_ADDR_WIDTH-1:0] reg_wr_addr,
input wire [31:0] reg_wr_data, input wire [REG_DATA_WIDTH-1:0] reg_wr_data,
input wire [3:0] reg_wr_strb, input wire [REG_STRB_WIDTH-1:0] reg_wr_strb,
input wire reg_wr_en, input wire reg_wr_en,
output wire reg_wr_wait, output wire reg_wr_wait,
output wire reg_wr_ack, output wire reg_wr_ack,
input wire [6:0] reg_rd_addr, input wire [REG_ADDR_WIDTH-1:0] reg_rd_addr,
input wire reg_rd_en, input wire reg_rd_en,
output wire [31:0] reg_rd_data, output wire [REG_DATA_WIDTH-1:0] reg_rd_data,
output wire reg_rd_wait, output wire reg_rd_wait,
output wire reg_rd_ack, output wire reg_rd_ack,
@ -77,9 +82,34 @@ module mqnic_ptp_clock #
output wire ptp_ts_step output wire ptp_ts_step
); );
localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}};
// check configuration
initial begin
if (REG_DATA_WIDTH != 32) begin
$error("Error: Register interface width must be 32 (instance %m)");
$finish;
end
if (REG_STRB_WIDTH * 8 != REG_DATA_WIDTH) begin
$error("Error: Register interface requires byte (8-bit) granularity (instance %m)");
$finish;
end
if (REG_ADDR_WIDTH < 7) begin
$error("Error: Register address width too narrow (instance %m)");
$finish;
end
if (RB_NEXT_PTR >= RB_BASE_ADDR && RB_NEXT_PTR < RB_BASE_ADDR + 7'h60) begin
$error("Error: RB_NEXT_PTR overlaps block (instance %m)");
$finish;
end
end
// control registers // control registers
reg reg_wr_ack_reg = 1'b0; reg reg_wr_ack_reg = 1'b0;
reg [31:0] reg_rd_data_reg = 0; reg [REG_DATA_WIDTH-1:0] reg_rd_data_reg = 0;
reg reg_rd_ack_reg = 1'b0; reg reg_rd_ack_reg = 1'b0;
reg [95:0] get_ptp_ts_96_reg = 0; reg [95:0] get_ptp_ts_96_reg = 0;
@ -114,23 +144,23 @@ always @(posedge clk) begin
reg_wr_ack_reg <= 1'b1; reg_wr_ack_reg <= 1'b1;
case ({reg_wr_addr >> 2, 2'b00}) case ({reg_wr_addr >> 2, 2'b00})
// PHC // PHC
7'h30: set_ptp_ts_96_reg[15:0] <= reg_wr_data; // PTP set fns RBB+7'h30: set_ptp_ts_96_reg[15:0] <= reg_wr_data; // PTP set fns
7'h34: set_ptp_ts_96_reg[45:16] <= reg_wr_data; // PTP set ns RBB+7'h34: set_ptp_ts_96_reg[45:16] <= reg_wr_data; // PTP set ns
7'h38: set_ptp_ts_96_reg[79:48] <= reg_wr_data; // PTP set sec l RBB+7'h38: set_ptp_ts_96_reg[79:48] <= reg_wr_data; // PTP set sec l
7'h3C: begin RBB+7'h3C: begin
// PTP set sec h // PTP set sec h
set_ptp_ts_96_reg[95:80] <= reg_wr_data; set_ptp_ts_96_reg[95:80] <= reg_wr_data;
set_ptp_ts_96_valid_reg <= 1'b1; set_ptp_ts_96_valid_reg <= 1'b1;
end end
7'h40: set_ptp_period_fns_reg <= reg_wr_data; // PTP period fns RBB+7'h40: set_ptp_period_fns_reg <= reg_wr_data; // PTP period fns
7'h44: begin RBB+7'h44: begin
// PTP period ns // PTP period ns
set_ptp_period_ns_reg <= reg_wr_data; set_ptp_period_ns_reg <= reg_wr_data;
set_ptp_period_valid_reg <= 1'b1; set_ptp_period_valid_reg <= 1'b1;
end end
7'h50: set_ptp_offset_fns_reg <= reg_wr_data; // PTP offset fns RBB+7'h50: set_ptp_offset_fns_reg <= reg_wr_data; // PTP offset fns
7'h54: set_ptp_offset_ns_reg <= reg_wr_data; // PTP offset ns RBB+7'h54: set_ptp_offset_ns_reg <= reg_wr_data; // PTP offset ns
7'h58: begin RBB+7'h58: begin
// PTP offset count // PTP offset count
set_ptp_offset_count_reg <= reg_wr_data; set_ptp_offset_count_reg <= reg_wr_data;
set_ptp_offset_valid_reg <= 1'b1; set_ptp_offset_valid_reg <= 1'b1;
@ -144,37 +174,40 @@ always @(posedge clk) begin
reg_rd_ack_reg <= 1'b1; reg_rd_ack_reg <= 1'b1;
case ({reg_rd_addr >> 2, 2'b00}) case ({reg_rd_addr >> 2, 2'b00})
// PHC // PHC
7'h00: begin RBB+7'h00: reg_rd_data_reg <= 32'h0000C080; // PHC: Type
RBB+7'h04: reg_rd_data_reg <= 32'h00000100; // PHC: Version
RBB+7'h08: reg_rd_data_reg <= RB_NEXT_PTR; // PHC: Next header
RBB+7'h0C: begin
// PHC features // PHC features
reg_rd_data_reg[7:0] <= PTP_PEROUT_ENABLE ? PTP_PEROUT_COUNT : 0; reg_rd_data_reg[7:0] <= PTP_PEROUT_ENABLE ? PTP_PEROUT_COUNT : 0;
reg_rd_data_reg[15:8] <= 0; reg_rd_data_reg[15:8] <= 0;
reg_rd_data_reg[23:16] <= 0; reg_rd_data_reg[23:16] <= 0;
reg_rd_data_reg[31:24] <= 0; reg_rd_data_reg[31:24] <= 0;
end end
7'h10: reg_rd_data_reg <= ptp_ts_96[15:0]; // PTP cur fns RBB+7'h10: reg_rd_data_reg <= ptp_ts_96[15:0]; // PTP cur fns
7'h14: reg_rd_data_reg <= ptp_ts_96[45:16]; // PTP cur ns RBB+7'h14: reg_rd_data_reg <= ptp_ts_96[45:16]; // PTP cur ns
7'h18: reg_rd_data_reg <= ptp_ts_96[79:48]; // PTP cur sec l RBB+7'h18: reg_rd_data_reg <= ptp_ts_96[79:48]; // PTP cur sec l
7'h1C: reg_rd_data_reg <= ptp_ts_96[95:80]; // PTP cur sec h RBB+7'h1C: reg_rd_data_reg <= ptp_ts_96[95:80]; // PTP cur sec h
7'h20: begin RBB+7'h20: begin
// PTP get fns // PTP get fns
get_ptp_ts_96_reg <= ptp_ts_96; get_ptp_ts_96_reg <= ptp_ts_96;
reg_rd_data_reg <= ptp_ts_96[15:0]; reg_rd_data_reg <= ptp_ts_96[15:0];
end end
7'h24: reg_rd_data_reg <= get_ptp_ts_96_reg[45:16]; // PTP get ns RBB+7'h24: reg_rd_data_reg <= get_ptp_ts_96_reg[45:16]; // PTP get ns
7'h28: reg_rd_data_reg <= get_ptp_ts_96_reg[79:48]; // PTP get sec l RBB+7'h28: reg_rd_data_reg <= get_ptp_ts_96_reg[79:48]; // PTP get sec l
7'h2C: reg_rd_data_reg <= get_ptp_ts_96_reg[95:80]; // PTP get sec h RBB+7'h2C: reg_rd_data_reg <= get_ptp_ts_96_reg[95:80]; // PTP get sec h
7'h30: reg_rd_data_reg <= set_ptp_ts_96_reg[15:0]; // PTP set fns RBB+7'h30: reg_rd_data_reg <= set_ptp_ts_96_reg[15:0]; // PTP set fns
7'h34: reg_rd_data_reg <= set_ptp_ts_96_reg[45:16]; // PTP set ns RBB+7'h34: reg_rd_data_reg <= set_ptp_ts_96_reg[45:16]; // PTP set ns
7'h38: reg_rd_data_reg <= set_ptp_ts_96_reg[79:48]; // PTP set sec l RBB+7'h38: reg_rd_data_reg <= set_ptp_ts_96_reg[79:48]; // PTP set sec l
7'h3C: reg_rd_data_reg <= set_ptp_ts_96_reg[95:80]; // PTP set sec h RBB+7'h3C: reg_rd_data_reg <= set_ptp_ts_96_reg[95:80]; // PTP set sec h
7'h40: reg_rd_data_reg <= set_ptp_period_fns_reg; // PTP period fns RBB+7'h40: reg_rd_data_reg <= set_ptp_period_fns_reg; // PTP period fns
7'h44: reg_rd_data_reg <= set_ptp_period_ns_reg; // PTP period ns RBB+7'h44: reg_rd_data_reg <= set_ptp_period_ns_reg; // PTP period ns
7'h48: reg_rd_data_reg <= PTP_PERIOD_FNS; // PTP nom period fns RBB+7'h48: reg_rd_data_reg <= PTP_PERIOD_FNS; // PTP nom period fns
7'h4C: reg_rd_data_reg <= PTP_PERIOD_NS; // PTP nom period ns RBB+7'h4C: reg_rd_data_reg <= PTP_PERIOD_NS; // PTP nom period ns
7'h50: reg_rd_data_reg <= set_ptp_offset_fns_reg; // PTP offset fns RBB+7'h50: reg_rd_data_reg <= set_ptp_offset_fns_reg; // PTP offset fns
7'h54: reg_rd_data_reg <= set_ptp_offset_ns_reg; // PTP offset ns RBB+7'h54: reg_rd_data_reg <= set_ptp_offset_ns_reg; // PTP offset ns
7'h58: reg_rd_data_reg <= set_ptp_offset_count_reg; // PTP offset count RBB+7'h58: reg_rd_data_reg <= set_ptp_offset_count_reg; // PTP offset count
7'h5C: reg_rd_data_reg <= set_ptp_offset_active; // PTP offset status RBB+7'h5C: reg_rd_data_reg <= set_ptp_offset_active; // PTP offset status
default: reg_rd_ack_reg <= 1'b0; default: reg_rd_ack_reg <= 1'b0;
endcase endcase
end end

View File

@ -40,7 +40,14 @@ either expressed or implied, of The Regents of the University of California.
/* /*
* PTP period output * PTP period output
*/ */
module mqnic_ptp_perout module mqnic_ptp_perout #
(
parameter REG_ADDR_WIDTH = 6,
parameter REG_DATA_WIDTH = 32,
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
parameter RB_BASE_ADDR = 0,
parameter RB_NEXT_PTR = 0
)
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
@ -48,15 +55,15 @@ module mqnic_ptp_perout
/* /*
* Register interface * Register interface
*/ */
input wire [6:0] reg_wr_addr, input wire [REG_ADDR_WIDTH-1:0] reg_wr_addr,
input wire [31:0] reg_wr_data, input wire [REG_DATA_WIDTH-1:0] reg_wr_data,
input wire [3:0] reg_wr_strb, input wire [REG_STRB_WIDTH-1:0] reg_wr_strb,
input wire reg_wr_en, input wire reg_wr_en,
output wire reg_wr_wait, output wire reg_wr_wait,
output wire reg_wr_ack, output wire reg_wr_ack,
input wire [6:0] reg_rd_addr, input wire [REG_ADDR_WIDTH-1:0] reg_rd_addr,
input wire reg_rd_en, input wire reg_rd_en,
output wire [31:0] reg_rd_data, output wire [REG_DATA_WIDTH-1:0] reg_rd_data,
output wire reg_rd_wait, output wire reg_rd_wait,
output wire reg_rd_ack, output wire reg_rd_ack,
@ -70,11 +77,36 @@ module mqnic_ptp_perout
output wire ptp_perout_pulse output wire ptp_perout_pulse
); );
localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}};
// check configuration
initial begin
if (REG_DATA_WIDTH != 32) begin
$error("Error: Register interface width must be 32 (instance %m)");
$finish;
end
if (REG_STRB_WIDTH * 8 != REG_DATA_WIDTH) begin
$error("Error: Register interface requires byte (8-bit) granularity (instance %m)");
$finish;
end
if (REG_ADDR_WIDTH < 6) begin
$error("Error: Register address width too narrow (instance %m)");
$finish;
end
if (RB_NEXT_PTR >= RB_BASE_ADDR && RB_NEXT_PTR < RB_BASE_ADDR + 7'h40) begin
$error("Error: RB_NEXT_PTR overlaps block (instance %m)");
$finish;
end
end
reg ptp_perout_enable_reg = 1'b0; reg ptp_perout_enable_reg = 1'b0;
// control registers // control registers
reg reg_wr_ack_reg = 1'b0; reg reg_wr_ack_reg = 1'b0;
reg [31:0] reg_rd_data_reg = 0; reg [REG_DATA_WIDTH-1:0] reg_rd_data_reg = 0;
reg reg_rd_ack_reg = 1'b0; reg reg_rd_ack_reg = 1'b0;
reg [95:0] set_ptp_perout_start_reg = 0; reg [95:0] set_ptp_perout_start_reg = 0;
@ -103,30 +135,30 @@ always @(posedge clk) begin
// write operation // write operation
reg_wr_ack_reg <= 1'b1; reg_wr_ack_reg <= 1'b1;
case ({reg_wr_addr >> 2, 2'b00}) case ({reg_wr_addr >> 2, 2'b00})
6'h00: begin RBB+6'h0C: begin
// PTP perout control // PTP perout control and status
ptp_perout_enable_reg <= reg_wr_data[0]; ptp_perout_enable_reg <= reg_wr_data[0];
end end
6'h10: set_ptp_perout_start_reg[15:0] <= reg_wr_data; // PTP perout start fns RBB+6'h10: set_ptp_perout_start_reg[15:0] <= reg_wr_data; // PTP perout start fns
6'h14: set_ptp_perout_start_reg[45:16] <= reg_wr_data; // PTP perout start ns RBB+6'h14: set_ptp_perout_start_reg[45:16] <= reg_wr_data; // PTP perout start ns
6'h18: set_ptp_perout_start_reg[79:48] <= reg_wr_data; // PTP perout start sec l RBB+6'h18: set_ptp_perout_start_reg[79:48] <= reg_wr_data; // PTP perout start sec l
6'h1C: begin RBB+6'h1C: begin
// PTP perout start sec h // PTP perout start sec h
set_ptp_perout_start_reg[95:80] <= reg_wr_data; set_ptp_perout_start_reg[95:80] <= reg_wr_data;
set_ptp_perout_start_valid_reg <= 1'b1; set_ptp_perout_start_valid_reg <= 1'b1;
end end
6'h20: set_ptp_perout_period_reg[15:0] <= reg_wr_data; // PTP perout period fns RBB+6'h20: set_ptp_perout_period_reg[15:0] <= reg_wr_data; // PTP perout period fns
6'h24: set_ptp_perout_period_reg[45:16] <= reg_wr_data; // PTP perout period ns RBB+6'h24: set_ptp_perout_period_reg[45:16] <= reg_wr_data; // PTP perout period ns
6'h28: set_ptp_perout_period_reg[79:48] <= reg_wr_data; // PTP perout period sec l RBB+6'h28: set_ptp_perout_period_reg[79:48] <= reg_wr_data; // PTP perout period sec l
6'h2C: begin RBB+6'h2C: begin
// PTP perout period sec h // PTP perout period sec h
set_ptp_perout_period_reg[95:80] <= reg_wr_data; set_ptp_perout_period_reg[95:80] <= reg_wr_data;
set_ptp_perout_period_valid_reg <= 1'b1; set_ptp_perout_period_valid_reg <= 1'b1;
end end
6'h30: set_ptp_perout_width_reg[15:0] <= reg_wr_data; // PTP perout width fns RBB+6'h30: set_ptp_perout_width_reg[15:0] <= reg_wr_data; // PTP perout width fns
6'h34: set_ptp_perout_width_reg[45:16] <= reg_wr_data; // PTP perout width ns RBB+6'h34: set_ptp_perout_width_reg[45:16] <= reg_wr_data; // PTP perout width ns
6'h38: set_ptp_perout_width_reg[79:48] <= reg_wr_data; // PTP perout width sec l RBB+6'h38: set_ptp_perout_width_reg[79:48] <= reg_wr_data; // PTP perout width sec l
6'h3C: begin RBB+6'h3C: begin
// PTP perout width sec h // PTP perout width sec h
set_ptp_perout_width_reg[95:80] <= reg_wr_data; set_ptp_perout_width_reg[95:80] <= reg_wr_data;
set_ptp_perout_width_valid_reg <= 1'b1; set_ptp_perout_width_valid_reg <= 1'b1;
@ -139,28 +171,28 @@ always @(posedge clk) begin
// read operation // read operation
reg_rd_ack_reg <= 1'b1; reg_rd_ack_reg <= 1'b1;
case ({reg_rd_addr >> 2, 2'b00}) case ({reg_rd_addr >> 2, 2'b00})
6'h00: begin RBB+6'h00: reg_rd_data_reg <= 32'h0000C081; // PHC: Type
// PTP perout control RBB+6'h04: reg_rd_data_reg <= 32'h00000100; // PHC: Version
RBB+6'h08: reg_rd_data_reg <= RB_NEXT_PTR; // PHC: Next header
RBB+6'h0C: begin
// PTP perout control and status
reg_rd_data_reg[0] <= ptp_perout_enable_reg; reg_rd_data_reg[0] <= ptp_perout_enable_reg;
reg_rd_data_reg[8] <= ptp_perout_pulse;
reg_rd_data_reg[16] <= ptp_perout_locked;
reg_rd_data_reg[24] <= ptp_perout_error;
end end
6'h04: begin RBB+6'h10: reg_rd_data_reg <= set_ptp_perout_start_reg[15:0]; // PTP perout start fns
// PTP perout status RBB+6'h14: reg_rd_data_reg <= set_ptp_perout_start_reg[45:16]; // PTP perout start ns
reg_rd_data_reg[0] <= ptp_perout_pulse; RBB+6'h18: reg_rd_data_reg <= set_ptp_perout_start_reg[79:48]; // PTP perout start sec l
reg_rd_data_reg[8] <= ptp_perout_locked; RBB+6'h1C: reg_rd_data_reg <= set_ptp_perout_start_reg[95:80]; // PTP perout start sec h
reg_rd_data_reg[16] <= ptp_perout_error; RBB+6'h20: reg_rd_data_reg <= set_ptp_perout_period_reg[15:0]; // PTP perout period fns
end RBB+6'h24: reg_rd_data_reg <= set_ptp_perout_period_reg[45:16]; // PTP perout period ns
6'h10: reg_rd_data_reg <= set_ptp_perout_start_reg[15:0]; // PTP perout start fns RBB+6'h28: reg_rd_data_reg <= set_ptp_perout_period_reg[79:48]; // PTP perout period sec l
6'h14: reg_rd_data_reg <= set_ptp_perout_start_reg[45:16]; // PTP perout start ns RBB+6'h2C: reg_rd_data_reg <= set_ptp_perout_period_reg[95:80]; // PTP perout period sec h
6'h18: reg_rd_data_reg <= set_ptp_perout_start_reg[79:48]; // PTP perout start sec l RBB+6'h30: reg_rd_data_reg <= set_ptp_perout_width_reg[15:0]; // PTP perout width fns
6'h1C: reg_rd_data_reg <= set_ptp_perout_start_reg[95:80]; // PTP perout start sec h RBB+6'h34: reg_rd_data_reg <= set_ptp_perout_width_reg[45:16]; // PTP perout width ns
6'h20: reg_rd_data_reg <= set_ptp_perout_period_reg[15:0]; // PTP perout period fns RBB+6'h38: reg_rd_data_reg <= set_ptp_perout_width_reg[79:48]; // PTP perout width sec l
6'h24: reg_rd_data_reg <= set_ptp_perout_period_reg[45:16]; // PTP perout period ns RBB+6'h3C: reg_rd_data_reg <= set_ptp_perout_width_reg[95:80]; // PTP perout width sec h
6'h28: reg_rd_data_reg <= set_ptp_perout_period_reg[79:48]; // PTP perout period sec l
6'h2C: reg_rd_data_reg <= set_ptp_perout_period_reg[95:80]; // PTP perout period sec h
6'h30: reg_rd_data_reg <= set_ptp_perout_width_reg[15:0]; // PTP perout width fns
6'h34: reg_rd_data_reg <= set_ptp_perout_width_reg[45:16]; // PTP perout width ns
6'h38: reg_rd_data_reg <= set_ptp_perout_width_reg[79:48]; // PTP perout width sec l
6'h3C: reg_rd_data_reg <= set_ptp_perout_width_reg[95:80]; // PTP perout width sec h
default: reg_rd_ack_reg <= 1'b0; default: reg_rd_ack_reg <= 1'b0;
endcase endcase
end end

View File

@ -48,6 +48,10 @@ module mqnic_tx_scheduler_block #
parameter REG_DATA_WIDTH = 32, parameter REG_DATA_WIDTH = 32,
// Width of control register interface strb // Width of control register interface strb
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8), parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
// Register block base address
parameter RB_BASE_ADDR = 0,
// Register block next pointer
parameter RB_NEXT_PTR = 0,
// Width of AXI lite data bus in bits // Width of AXI lite data bus in bits
parameter AXIL_DATA_WIDTH = 32, parameter AXIL_DATA_WIDTH = 32,
// Width of AXI lite address bus in bits // Width of AXI lite address bus in bits
@ -146,6 +150,8 @@ module mqnic_tx_scheduler_block #
parameter SCHED_COUNT = 1; parameter SCHED_COUNT = 1;
parameter AXIL_SCHED_ADDR_WIDTH = AXIL_ADDR_WIDTH-$clog2(SCHED_COUNT); parameter AXIL_SCHED_ADDR_WIDTH = AXIL_ADDR_WIDTH-$clog2(SCHED_COUNT);
localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}};
// control registers // control registers
reg ctrl_reg_wr_ack_reg = 1'b0; reg ctrl_reg_wr_ack_reg = 1'b0;
reg [REG_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = 0; reg [REG_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = 0;
@ -168,8 +174,9 @@ always @(posedge clk) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b1; ctrl_reg_wr_ack_reg <= 1'b1;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // Scheduler
// Scheduler enable RBB+8'h28: begin
// Sched: Control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sched_enable_reg <= ctrl_reg_wr_data[0]; sched_enable_reg <= ctrl_reg_wr_data[0];
end end
@ -182,14 +189,23 @@ always @(posedge clk) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0010: ctrl_reg_rd_data_reg <= SCHED_COUNT; // scheduler_count // Scheduler block
16'h0014: ctrl_reg_rd_data_reg <= AXIL_OFFSET; // scheduler_offset RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C003; // Sched block: Type
16'h0018: ctrl_reg_rd_data_reg <= 2**AXIL_SCHED_ADDR_WIDTH; // scheduler_stride RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // Sched block: Version
16'h001C: ctrl_reg_rd_data_reg <= 32'd0; // scheduler_type RBB+8'h08: ctrl_reg_rd_data_reg <= RB_NEXT_PTR; // Sched block: Next header
16'h0040: begin RBB+8'h0C: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // Sched block: Offset
// Scheduler enable // Round-robin scheduler
RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C040; // Sched: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // Sched: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= 0; // Sched: Next header
RBB+8'h1C: ctrl_reg_rd_data_reg <= AXIL_OFFSET; // Sched: Offset
RBB+8'h20: ctrl_reg_rd_data_reg <= 2**QUEUE_INDEX_WIDTH; // Sched: Channel count
RBB+8'h24: ctrl_reg_rd_data_reg <= 4; // Sched: Channel stride
RBB+8'h28: begin
// Sched: Control
ctrl_reg_rd_data_reg[0] <= sched_enable_reg; ctrl_reg_rd_data_reg[0] <= sched_enable_reg;
end end
RBB+8'h2C: ctrl_reg_rd_data_reg <= 0; // Sched: dest
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end

View File

@ -48,6 +48,10 @@ module mqnic_tx_scheduler_block #
parameter REG_DATA_WIDTH = 32, parameter REG_DATA_WIDTH = 32,
// Width of control register interface strb // Width of control register interface strb
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8), parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
// Register block base address
parameter RB_BASE_ADDR = 0,
// Register block next pointer
parameter RB_NEXT_PTR = 0,
// Width of AXI lite data bus in bits // Width of AXI lite data bus in bits
parameter AXIL_DATA_WIDTH = 32, parameter AXIL_DATA_WIDTH = 32,
// Width of AXI lite address bus in bits // Width of AXI lite address bus in bits
@ -146,6 +150,8 @@ module mqnic_tx_scheduler_block #
parameter SCHED_COUNT = 2; parameter SCHED_COUNT = 2;
parameter AXIL_SCHED_ADDR_WIDTH = AXIL_ADDR_WIDTH-$clog2(SCHED_COUNT); parameter AXIL_SCHED_ADDR_WIDTH = AXIL_ADDR_WIDTH-$clog2(SCHED_COUNT);
localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}};
// parameter sizing helpers // parameter sizing helpers
function [31:0] w_32(input [31:0] val); function [31:0] w_32(input [31:0] val);
w_32 = val; w_32 = val;
@ -224,43 +230,52 @@ always @(posedge clk) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b1; ctrl_reg_wr_ack_reg <= 1'b1;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // Scheduler
// Scheduler enable RBB+8'h28: begin
// Sched: Control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sched_enable_reg <= ctrl_reg_wr_data[0]; sched_enable_reg <= ctrl_reg_wr_data[0];
end end
end end
16'h1000: begin // TDMA scheduler controller
// TDMA control RBB+8'h48: begin
// Sched ctrl: Control
if (ctrl_reg_wr_strb[0]) begin
// sched_enable_reg <= ctrl_reg_wr_data[0];
end
end
// TDMA scheduler
RBB+8'h60: begin
// TDMA: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
tdma_enable_reg <= ctrl_reg_wr_data[0]; tdma_enable_reg <= ctrl_reg_wr_data[0];
end end
end end
16'h1014: set_tdma_schedule_start_reg[29:0] <= ctrl_reg_wr_data; // TDMA schedule start ns RBB+8'h74: set_tdma_schedule_start_reg[29:0] <= ctrl_reg_wr_data; // TDMA: schedule start ns
16'h1018: set_tdma_schedule_start_reg[63:32] <= ctrl_reg_wr_data; // TDMA schedule start sec l RBB+8'h78: set_tdma_schedule_start_reg[63:32] <= ctrl_reg_wr_data; // TDMA: schedule start sec l
16'h101C: begin RBB+8'h7C: begin
// TDMA schedule start sec h // TDMA: schedule start sec h
set_tdma_schedule_start_reg[79:64] <= ctrl_reg_wr_data; set_tdma_schedule_start_reg[79:64] <= ctrl_reg_wr_data;
set_tdma_schedule_start_valid_reg <= 1'b1; set_tdma_schedule_start_valid_reg <= 1'b1;
end end
16'h1024: set_tdma_schedule_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA schedule period ns RBB+8'h84: set_tdma_schedule_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA: schedule period ns
16'h1028: set_tdma_schedule_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA schedule period sec l RBB+8'h88: set_tdma_schedule_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA: schedule period sec l
16'h102C: begin RBB+8'h8C: begin
// TDMA schedule period sec h // TDMA: schedule period sec h
set_tdma_schedule_period_reg[79:64] <= ctrl_reg_wr_data; set_tdma_schedule_period_reg[79:64] <= ctrl_reg_wr_data;
set_tdma_schedule_period_valid_reg <= 1'b1; set_tdma_schedule_period_valid_reg <= 1'b1;
end end
16'h1034: set_tdma_timeslot_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA timeslot period ns RBB+8'h94: set_tdma_timeslot_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA: timeslot period ns
16'h1038: set_tdma_timeslot_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA timeslot period sec l RBB+8'h98: set_tdma_timeslot_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA: timeslot period sec l
16'h103C: begin RBB+8'h9C: begin
// TDMA timeslot period sec h // TDMA: timeslot period sec h
set_tdma_timeslot_period_reg[79:64] <= ctrl_reg_wr_data; set_tdma_timeslot_period_reg[79:64] <= ctrl_reg_wr_data;
set_tdma_timeslot_period_valid_reg <= 1'b1; set_tdma_timeslot_period_valid_reg <= 1'b1;
end end
16'h1044: set_tdma_active_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA active period ns RBB+8'hA4: set_tdma_active_period_reg[29:0] <= ctrl_reg_wr_data; // TDMA: active period ns
16'h1048: set_tdma_active_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA active period sec l RBB+8'hA8: set_tdma_active_period_reg[63:32] <= ctrl_reg_wr_data; // TDMA: active period sec l
16'h104C: begin RBB+8'hAC: begin
// TDMA active period sec h // TDMA: active period sec h
set_tdma_active_period_reg[79:64] <= ctrl_reg_wr_data; set_tdma_active_period_reg[79:64] <= ctrl_reg_wr_data;
set_tdma_active_period_valid_reg <= 1'b1; set_tdma_active_period_valid_reg <= 1'b1;
end end
@ -272,36 +287,61 @@ always @(posedge clk) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0010: ctrl_reg_rd_data_reg <= SCHED_COUNT; // scheduler_count // Scheduler block
16'h0014: ctrl_reg_rd_data_reg <= AXIL_OFFSET; // scheduler_offset RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C003; // Sched block: Type
16'h0018: ctrl_reg_rd_data_reg <= 2**AXIL_SCHED_ADDR_WIDTH; // scheduler_stride RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // Sched block: Version
16'h001C: ctrl_reg_rd_data_reg <= 32'd0; // scheduler_type RBB+8'h08: ctrl_reg_rd_data_reg <= RB_NEXT_PTR; // Sched block: Next header
16'h0040: begin RBB+8'h0C: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // Sched block: Offset
// Scheduler enable // Scheduler
RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C040; // Sched: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // Sched: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // Sched: Next header
RBB+8'h1C: ctrl_reg_rd_data_reg <= AXIL_OFFSET; // Sched: Offset
RBB+8'h20: ctrl_reg_rd_data_reg <= 2**QUEUE_INDEX_WIDTH; // Sched: Channel count
RBB+8'h24: ctrl_reg_rd_data_reg <= 4; // Sched: Channel stride
RBB+8'h28: begin
// Sched: Control
ctrl_reg_rd_data_reg[0] <= sched_enable_reg; ctrl_reg_rd_data_reg[0] <= sched_enable_reg;
end end
16'h1000: begin RBB+8'h2C: ctrl_reg_rd_data_reg <= 0; // Sched: dest
// TDMA control // TDMA scheduler controller
RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C050; // Sched ctrl: Type
RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // Sched ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // Sched ctrl: Next header
RBB+8'h3C: ctrl_reg_rd_data_reg <= AXIL_OFFSET+2**(AXIL_ADDR_WIDTH-1); // Sched ctrl: Offset
RBB+8'h40: ctrl_reg_rd_data_reg <= 2**QUEUE_INDEX_WIDTH; // Sched ctrl: Channel count
RBB+8'h44: ctrl_reg_rd_data_reg <= 4*((2**TDMA_INDEX_WIDTH+31)/32); // Sched ctrl: Channel stride
RBB+8'h48: begin
// Sched ctrl: Control
ctrl_reg_rd_data_reg[0] <= 1'b1;
end
RBB+8'h4C: ctrl_reg_rd_data_reg <= 2**TDMA_INDEX_WIDTH; // Sched ctrl: Timeslot count
// TDMA scheduler
RBB+8'h50: ctrl_reg_rd_data_reg <= 32'h0000C060; // TDMA: Type
RBB+8'h54: ctrl_reg_rd_data_reg <= 32'h00000100; // TDMA: Version
RBB+8'h58: ctrl_reg_rd_data_reg <= 0; // TDMA: Next header
RBB+8'h5C: ctrl_reg_rd_data_reg <= 2**TDMA_INDEX_WIDTH; // TDMA: Timeslot count
RBB+8'h60: begin
// TDMA: control
ctrl_reg_rd_data_reg[0] <= tdma_enable_reg; ctrl_reg_rd_data_reg[0] <= tdma_enable_reg;
end end
16'h1004: begin RBB+8'h64: begin
// TDMA status // TDMA: status
ctrl_reg_rd_data_reg[0] <= tdma_locked; ctrl_reg_rd_data_reg[0] <= tdma_locked;
ctrl_reg_rd_data_reg[1] <= tdma_error; ctrl_reg_rd_data_reg[1] <= tdma_error;
end end
16'h1008: ctrl_reg_rd_data_reg <= 2**TDMA_INDEX_WIDTH; // TDMA timeslot count RBB+8'h74: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[29:0]; // TDMA: schedule start ns
16'h1014: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[29:0]; // TDMA schedule start ns RBB+8'h78: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[63:32]; // TDMA: schedule start sec l
16'h1018: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[63:32]; // TDMA schedule start sec l RBB+8'h7C: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[79:64]; // TDMA: schedule start sec h
16'h101C: ctrl_reg_rd_data_reg <= set_tdma_schedule_start_reg[79:64]; // TDMA schedule start sec h RBB+8'h84: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[29:0]; // TDMA: schedule period ns
16'h1024: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[29:0]; // TDMA schedule period ns RBB+8'h88: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[63:32]; // TDMA: schedule period sec l
16'h1028: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[63:32]; // TDMA schedule period sec l RBB+8'h8C: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[79:64]; // TDMA: schedule period sec h
16'h102C: ctrl_reg_rd_data_reg <= set_tdma_schedule_period_reg[79:64]; // TDMA schedule period sec h RBB+8'h94: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[29:0]; // TDMA: timeslot period ns
16'h1034: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[29:0]; // TDMA timeslot period ns RBB+8'h98: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[63:32]; // TDMA: timeslot period sec l
16'h1038: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[63:32]; // TDMA timeslot period sec l RBB+8'h9C: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[79:64]; // TDMA: timeslot period sec h
16'h103C: ctrl_reg_rd_data_reg <= set_tdma_timeslot_period_reg[79:64]; // TDMA timeslot period sec h RBB+8'hA4: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[29:0]; // TDMA: active period ns
16'h1044: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[29:0]; // TDMA active period ns RBB+8'hA8: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[63:32]; // TDMA: active period sec l
16'h1048: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[63:32]; // TDMA active period sec l RBB+8'hAC: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[79:64]; // TDMA: active period sec h
16'h104C: ctrl_reg_rd_data_reg <= set_tdma_active_period_reg[79:64]; // TDMA active period sec h
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end

View File

@ -31,6 +31,7 @@ either expressed or implied, of The Regents of the University of California.
""" """
import datetime
from collections import deque from collections import deque
import cocotb import cocotb
@ -38,6 +39,8 @@ from cocotb.log import SimLog
from cocotb.queue import Queue from cocotb.queue import Queue
from cocotb.triggers import Event, Edge, RisingEdge from cocotb.triggers import Event, Edge, RisingEdge
from cocotbext.axi import Window
import struct import struct
MQNIC_MAX_EVENT_RINGS = 1 MQNIC_MAX_EVENT_RINGS = 1
@ -46,147 +49,201 @@ MQNIC_MAX_TX_CPL_RINGS = 32
MQNIC_MAX_RX_RINGS = 8 MQNIC_MAX_RX_RINGS = 8
MQNIC_MAX_RX_CPL_RINGS = 8 MQNIC_MAX_RX_CPL_RINGS = 8
MQNIC_QUEUE_STRIDE = 0x00000020 # Register blocks
MQNIC_CPL_QUEUE_STRIDE = 0x00000020 MQNIC_RB_REG_TYPE = 0x00
MQNIC_EVENT_QUEUE_STRIDE = 0x00000020 MQNIC_RB_REG_VER = 0x04
MQNIC_RB_REG_NEXT_PTR = 0x08
# NIC CSRs MQNIC_RB_FW_ID_TYPE = 0xFFFFFFFF
MQNIC_REG_FW_ID = 0x0000 MQNIC_RB_FW_ID_VER = 0x00000100
MQNIC_REG_FW_VER = 0x0004 MQNIC_RB_FW_ID_REG_FPGA_ID = 0x0C
MQNIC_REG_BOARD_ID = 0x0008 MQNIC_RB_FW_ID_REG_FW_ID = 0x10
MQNIC_REG_BOARD_VER = 0x000C MQNIC_RB_FW_ID_REG_FW_VER = 0x14
MQNIC_RB_FW_ID_REG_BOARD_ID = 0x18
MQNIC_RB_FW_ID_REG_BOARD_VER = 0x1C
MQNIC_RB_FW_ID_REG_BUILD_DATE = 0x20
MQNIC_RB_FW_ID_REG_GIT_HASH = 0x24
MQNIC_RB_FW_ID_REG_REL_INFO = 0x28
MQNIC_REG_PHC_COUNT = 0x0010 MQNIC_RB_GPIO_TYPE = 0x0000C100
MQNIC_REG_PHC_OFFSET = 0x0014 MQNIC_RB_GPIO_VER = 0x00000100
MQNIC_RB_GPIO_REG_GPIO_IN = 0x0C
MQNIC_RB_GPIO_REG_GPIO_OUT = 0x10
MQNIC_REG_IF_COUNT = 0x0020 MQNIC_RB_I2C_TYPE = 0x0000C110
MQNIC_REG_IF_STRIDE = 0x0024 MQNIC_RB_I2C_VER = 0x00000100
MQNIC_REG_IF_CSR_OFFSET = 0x002C MQNIC_RB_I2C_REG_CTRL = 0x0C
MQNIC_REG_FPGA_ID = 0x0040 MQNIC_RB_SPI_FLASH_TYPE = 0x0000C120
MQNIC_RB_SPI_FLASH_VER = 0x00000100
MQNIC_RB_SPI_FLASH_REG_FORMAT = 0x0C
MQNIC_RB_SPI_FLASH_REG_CTRL_0 = 0x10
MQNIC_RB_SPI_FLASH_REG_CTRL_1 = 0x14
MQNIC_REG_GPIO_OUT = 0x0100 MQNIC_RB_BPI_FLASH_TYPE = 0x0000C121
MQNIC_REG_GPIO_IN = 0x0104 MQNIC_RB_BPI_FLASH_VER = 0x00000100
MQNIC_RB_BPI_FLASH_REG_FORMAT = 0x0C
MQNIC_RB_BPI_FLASH_REG_ADDR = 0x10
MQNIC_RB_BPI_FLASH_REG_DATA = 0x14
MQNIC_RB_BPI_FLASH_REG_CTRL = 0x18
MQNIC_REG_GPIO_I2C_0 = 0x0110 MQNIC_RB_ALVEO_BMC_TYPE = 0x0000C140
MQNIC_REG_GPIO_I2C_1 = 0x0114 MQNIC_RB_ALVEO_BMC_VER = 0x00000100
MQNIC_REG_GPIO_I2C_2 = 0x0118 MQNIC_RB_ALVEO_BMC_REG_ADDR = 0x0C
MQNIC_REG_GPIO_I2C_3 = 0x011C MQNIC_RB_ALVEO_BMC_REG_DATA = 0x10
MQNIC_REG_GPIO_I2C_SCL_IN = 0x00000001 MQNIC_RB_GECKO_BMC_TYPE = 0x0000C141
MQNIC_REG_GPIO_I2C_SCL_OUT = 0x00000002 MQNIC_RB_GECKO_BMC_VER = 0x00000100
MQNIC_REG_GPIO_I2C_SDA_IN = 0x00000100 MQNIC_RB_GECKO_BMC_REG_STATUS = 0x0C
MQNIC_REG_GPIO_I2C_SDA_OUT = 0x00000200 MQNIC_RB_GECKO_BMC_REG_DATA = 0x10
MQNIC_RB_GECKO_BMC_REG_CMD = 0x14
MQNIC_REG_GPIO_XCVR_0123 = 0x0120 MQNIC_RB_STATS_TYPE = 0x0000C004
MQNIC_REG_GPIO_XCVR_4567 = 0x0124 MQNIC_RB_STATS_VER = 0x00000100
MQNIC_RB_STATS_REG_OFFSET = 0x0C
MQNIC_RB_STATS_REG_COUNT = 0x10
MQNIC_RB_STATS_REG_STRIDE = 0x14
MQNIC_RB_STATS_REG_FLAGS = 0x18
MQNIC_REG_GPIO_XCVR_PRSNT_IN = 0x01 MQNIC_RB_PHC_TYPE = 0x0000C080
MQNIC_REG_GPIO_XCVR_TX_FAULT_INT_IN = 0x02 MQNIC_RB_PHC_VER = 0x00000100
MQNIC_REG_GPIO_XCVR_RX_LOS_IN = 0x03 MQNIC_RB_PHC_REG_CTRL = 0x0C
MQNIC_REG_GPIO_XCVR_RST_OUT = 0x10 MQNIC_RB_PHC_REG_CUR_FNS = 0x10
MQNIC_REG_GPIO_XCVR_TX_DIS_LPMODE_OUT = 0x20 MQNIC_RB_PHC_REG_CUR_NS = 0x14
MQNIC_REG_GPIO_XCVR_RS0_OUT = 0x40 MQNIC_RB_PHC_REG_CUR_SEC_L = 0x18
MQNIC_REG_GPIO_XCVR_RS1_OUT = 0x80 MQNIC_RB_PHC_REG_CUR_SEC_H = 0x1C
MQNIC_RB_PHC_REG_GET_FNS = 0x20
MQNIC_RB_PHC_REG_GET_NS = 0x24
MQNIC_RB_PHC_REG_GET_SEC_L = 0x28
MQNIC_RB_PHC_REG_GET_SEC_H = 0x2C
MQNIC_RB_PHC_REG_SET_FNS = 0x30
MQNIC_RB_PHC_REG_SET_NS = 0x34
MQNIC_RB_PHC_REG_SET_SEC_L = 0x38
MQNIC_RB_PHC_REG_SET_SEC_H = 0x3C
MQNIC_RB_PHC_REG_PERIOD_FNS = 0x40
MQNIC_RB_PHC_REG_PERIOD_NS = 0x44
MQNIC_RB_PHC_REG_NOM_PERIOD_FNS = 0x48
MQNIC_RB_PHC_REG_NOM_PERIOD_NS = 0x4C
MQNIC_RB_PHC_REG_ADJ_FNS = 0x50
MQNIC_RB_PHC_REG_ADJ_NS = 0x54
MQNIC_RB_PHC_REG_ADJ_COUNT = 0x58
MQNIC_RB_PHC_REG_ADJ_ACTIVE = 0x5C
MQNIC_PHC_REG_FEATURES = 0x0000 MQNIC_RB_PHC_PEROUT_TYPE = 0x0000C081
MQNIC_PHC_REG_PTP_CUR_FNS = 0x0010 MQNIC_RB_PHC_PEROUT_VER = 0x00000100
MQNIC_PHC_REG_PTP_CUR_NS = 0x0014 MQNIC_RB_PHC_PEROUT_REG_CTRL = 0x0C
MQNIC_PHC_REG_PTP_CUR_SEC_L = 0x0018 MQNIC_RB_PHC_PEROUT_REG_START_FNS = 0x10
MQNIC_PHC_REG_PTP_CUR_SEC_H = 0x001C MQNIC_RB_PHC_PEROUT_REG_START_NS = 0x14
MQNIC_PHC_REG_PTP_GET_FNS = 0x0020 MQNIC_RB_PHC_PEROUT_REG_START_SEC_L = 0x18
MQNIC_PHC_REG_PTP_GET_NS = 0x0024 MQNIC_RB_PHC_PEROUT_REG_START_SEC_H = 0x1C
MQNIC_PHC_REG_PTP_GET_SEC_L = 0x0028 MQNIC_RB_PHC_PEROUT_REG_PERIOD_FNS = 0x20
MQNIC_PHC_REG_PTP_GET_SEC_H = 0x002C MQNIC_RB_PHC_PEROUT_REG_PERIOD_NS = 0x24
MQNIC_PHC_REG_PTP_SET_FNS = 0x0030 MQNIC_RB_PHC_PEROUT_REG_PERIOD_SEC_L = 0x28
MQNIC_PHC_REG_PTP_SET_NS = 0x0034 MQNIC_RB_PHC_PEROUT_REG_PERIOD_SEC_H = 0x2C
MQNIC_PHC_REG_PTP_SET_SEC_L = 0x0038 MQNIC_RB_PHC_PEROUT_REG_WIDTH_FNS = 0x30
MQNIC_PHC_REG_PTP_SET_SEC_H = 0x003C MQNIC_RB_PHC_PEROUT_REG_WIDTH_NS = 0x34
MQNIC_PHC_REG_PTP_PERIOD_FNS = 0x0040 MQNIC_RB_PHC_PEROUT_REG_WIDTH_SEC_L = 0x38
MQNIC_PHC_REG_PTP_PERIOD_NS = 0x0044 MQNIC_RB_PHC_PEROUT_REG_WIDTH_SEC_H = 0x3C
MQNIC_PHC_REG_PTP_NOM_PERIOD_FNS = 0x0048
MQNIC_PHC_REG_PTP_NOM_PERIOD_NS = 0x004C
MQNIC_PHC_REG_PTP_ADJ_FNS = 0x0050
MQNIC_PHC_REG_PTP_ADJ_NS = 0x0054
MQNIC_PHC_REG_PTP_ADJ_COUNT = 0x0058
MQNIC_PHC_REG_PTP_ADJ_ACTIVE = 0x005C
MQNIC_PHC_REG_PEROUT_CTRL = 0x0000 MQNIC_RB_IF_TYPE = 0x0000C000
MQNIC_PHC_REG_PEROUT_STATUS = 0x0004 MQNIC_RB_IF_VER = 0x00000100
MQNIC_PHC_REG_PEROUT_START_FNS = 0x0010 MQNIC_RB_IF_REG_OFFSET = 0x0C
MQNIC_PHC_REG_PEROUT_START_NS = 0x0014 MQNIC_RB_IF_REG_COUNT = 0x10
MQNIC_PHC_REG_PEROUT_START_SEC_L = 0x0018 MQNIC_RB_IF_REG_STRIDE = 0x14
MQNIC_PHC_REG_PEROUT_START_SEC_H = 0x001C MQNIC_RB_IF_REG_CSR_OFFSET = 0x18
MQNIC_PHC_REG_PEROUT_PERIOD_FNS = 0x0020
MQNIC_PHC_REG_PEROUT_PERIOD_NS = 0x0024
MQNIC_PHC_REG_PEROUT_PERIOD_SEC_L = 0x0028
MQNIC_PHC_REG_PEROUT_PERIOD_SEC_H = 0x002C
MQNIC_PHC_REG_PEROUT_WIDTH_FNS = 0x0030
MQNIC_PHC_REG_PEROUT_WIDTH_NS = 0x0034
MQNIC_PHC_REG_PEROUT_WIDTH_SEC_L = 0x0038
MQNIC_PHC_REG_PEROUT_WIDTH_SEC_H = 0x003C
# Interface CSRs MQNIC_RB_IF_CTRL_TX_TYPE = 0x0000C001
MQNIC_IF_REG_IF_ID = 0x0000 MQNIC_RB_IF_CTRL_TX_VER = 0x00000100
MQNIC_IF_REG_IF_FEATURES = 0x0004 MQNIC_RB_IF_CTRL_TX_REG_FEATURES = 0x0C
MQNIC_RB_IF_CTRL_TX_REG_MAX_MTU = 0x10
MQNIC_RB_IF_CTRL_TX_REG_MTU = 0x14
MQNIC_IF_REG_EVENT_QUEUE_COUNT = 0x0010 MQNIC_IF_TX_FEATURE_PTP_TS = (1 << 4)
MQNIC_IF_REG_EVENT_QUEUE_OFFSET = 0x0014 MQNIC_IF_TX_FEATURE_CSUM = (1 << 8)
MQNIC_IF_REG_TX_QUEUE_COUNT = 0x0020
MQNIC_IF_REG_TX_QUEUE_OFFSET = 0x0024
MQNIC_IF_REG_TX_CPL_QUEUE_COUNT = 0x0028
MQNIC_IF_REG_TX_CPL_QUEUE_OFFSET = 0x002C
MQNIC_IF_REG_RX_QUEUE_COUNT = 0x0030
MQNIC_IF_REG_RX_QUEUE_OFFSET = 0x0034
MQNIC_IF_REG_RX_CPL_QUEUE_COUNT = 0x0038
MQNIC_IF_REG_RX_CPL_QUEUE_OFFSET = 0x003C
MQNIC_IF_REG_PORT_COUNT = 0x0040
MQNIC_IF_REG_PORT_OFFSET = 0x0044
MQNIC_IF_REG_PORT_STRIDE = 0x0048
MQNIC_IF_FEATURE_RSS = (1 << 0) MQNIC_RB_IF_CTRL_RX_TYPE = 0x0000C002
MQNIC_IF_FEATURE_PTP_TS = (1 << 4) MQNIC_RB_IF_CTRL_RX_VER = 0x00000100
MQNIC_IF_FEATURE_TX_CSUM = (1 << 8) MQNIC_RB_IF_CTRL_RX_REG_FEATURES = 0x0C
MQNIC_IF_FEATURE_RX_CSUM = (1 << 9) MQNIC_RB_IF_CTRL_RX_REG_MAX_MTU = 0x10
MQNIC_RB_IF_CTRL_RX_REG_MTU = 0x14
MQNIC_RB_IF_CTRL_RX_REG_RSS_MASK = 0x18
# Port CSRs MQNIC_IF_RX_FEATURE_RSS = (1 << 0)
MQNIC_PORT_REG_PORT_ID = 0x0000 MQNIC_IF_RX_FEATURE_PTP_TS = (1 << 4)
MQNIC_PORT_REG_PORT_FEATURES = 0x0004 MQNIC_IF_RX_FEATURE_CSUM = (1 << 8)
MQNIC_PORT_REG_PORT_MTU = 0x0008 MQNIC_IF_RX_FEATURE_HASH = (1 << 9)
MQNIC_PORT_REG_SCHED_COUNT = 0x0010 MQNIC_RB_EVENT_QM_TYPE = 0x0000C010
MQNIC_PORT_REG_SCHED_OFFSET = 0x0014 MQNIC_RB_EVENT_QM_VER = 0x00000100
MQNIC_PORT_REG_SCHED_STRIDE = 0x0018 MQNIC_RB_EVENT_QM_REG_OFFSET = 0x0C
MQNIC_PORT_REG_SCHED_TYPE = 0x001C MQNIC_RB_EVENT_QM_REG_COUNT = 0x10
MQNIC_PORT_REG_SCHED_ENABLE = 0x0040 MQNIC_RB_EVENT_QM_REG_STRIDE = 0x14
MQNIC_PORT_REG_TX_MTU = 0x0100 MQNIC_RB_TX_QM_TYPE = 0x0000C020
MQNIC_PORT_REG_RX_MTU = 0x0200 MQNIC_RB_TX_QM_VER = 0x00000100
MQNIC_RB_TX_QM_REG_OFFSET = 0x0C
MQNIC_RB_TX_QM_REG_COUNT = 0x10
MQNIC_RB_TX_QM_REG_STRIDE = 0x14
MQNIC_PORT_REG_TDMA_CTRL = 0x1000 MQNIC_RB_TX_CQM_TYPE = 0x0000C030
MQNIC_PORT_REG_TDMA_STATUS = 0x1004 MQNIC_RB_TX_CQM_VER = 0x00000100
MQNIC_PORT_REG_TDMA_TIMESLOT_COUNT = 0x1008 MQNIC_RB_TX_CQM_REG_OFFSET = 0x0C
MQNIC_PORT_REG_TDMA_SCHED_START_FNS = 0x1010 MQNIC_RB_TX_CQM_REG_COUNT = 0x10
MQNIC_PORT_REG_TDMA_SCHED_START_NS = 0x1014 MQNIC_RB_TX_CQM_REG_STRIDE = 0x14
MQNIC_PORT_REG_TDMA_SCHED_START_SEC_L = 0x1018
MQNIC_PORT_REG_TDMA_SCHED_START_SEC_H = 0x101C
MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS = 0x1020
MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS = 0x1024
MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L = 0x1028
MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H = 0x102C
MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS = 0x1030
MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS = 0x1034
MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L = 0x1038
MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H = 0x103C
MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS = 0x1040
MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS = 0x1044
MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L = 0x1048
MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H = 0x104C
MQNIC_PORT_FEATURE_RSS = (1 << 0) MQNIC_RB_RX_QM_TYPE = 0x0000C021
MQNIC_PORT_FEATURE_PTP_TS = (1 << 4) MQNIC_RB_RX_QM_VER = 0x00000100
MQNIC_PORT_FEATURE_TX_CSUM = (1 << 8) MQNIC_RB_RX_QM_REG_OFFSET = 0x0C
MQNIC_PORT_FEATURE_RX_CSUM = (1 << 9) MQNIC_RB_RX_QM_REG_COUNT = 0x10
MQNIC_RB_RX_QM_REG_STRIDE = 0x14
MQNIC_RB_RX_CQM_TYPE = 0x0000C031
MQNIC_RB_RX_CQM_VER = 0x00000100
MQNIC_RB_RX_CQM_REG_OFFSET = 0x0C
MQNIC_RB_RX_CQM_REG_COUNT = 0x10
MQNIC_RB_RX_CQM_REG_STRIDE = 0x14
MQNIC_RB_SCHED_BLOCK_TYPE = 0x0000C003
MQNIC_RB_SCHED_BLOCK_VER = 0x00000100
MQNIC_RB_SCHED_BLOCK_REG_OFFSET = 0x0C
MQNIC_RB_SCHED_RR_TYPE = 0x0000C040
MQNIC_RB_SCHED_RR_VER = 0x00000100
MQNIC_RB_SCHED_RR_REG_OFFSET = 0x0C
MQNIC_RB_SCHED_RR_REG_CH_COUNT = 0x10
MQNIC_RB_SCHED_RR_REG_CH_STRIDE = 0x14
MQNIC_RB_SCHED_RR_REG_CTRL = 0x18
MQNIC_RB_SCHED_RR_REG_DEST = 0x1C
MQNIC_RB_SCHED_CTRL_TDMA_TYPE = 0x0000C050
MQNIC_RB_SCHED_CTRL_TDMA_VER = 0x00000100
MQNIC_RB_SCHED_CTRL_TDMA_REG_OFFSET = 0x0C
MQNIC_RB_SCHED_CTRL_TDMA_REG_CH_COUNT = 0x10
MQNIC_RB_SCHED_CTRL_TDMA_REG_CH_STRIDE = 0x14
MQNIC_RB_SCHED_CTRL_TDMA_REG_CTRL = 0x18
MQNIC_RB_SCHED_CTRL_TDMA_REG_TS_COUNT = 0x1C
MQNIC_RB_TDMA_SCH_TYPE = 0x0000C060
MQNIC_RB_TDMA_SCH_VER = 0x00000100
MQNIC_RB_TDMA_SCH_REG_TS_COUNT = 0x0C
MQNIC_RB_TDMA_SCH_REG_CTRL = 0x10
MQNIC_RB_TDMA_SCH_REG_STATUS = 0x14
MQNIC_RB_TDMA_SCH_REG_SCH_START_FNS = 0x20
MQNIC_RB_TDMA_SCH_REG_SCH_START_NS = 0x24
MQNIC_RB_TDMA_SCH_REG_SCH_START_SEC_L = 0x28
MQNIC_RB_TDMA_SCH_REG_SCH_START_SEC_H = 0x2C
MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_FNS = 0x30
MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_NS = 0x34
MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_SEC_L = 0x38
MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_SEC_H = 0x3C
MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_FNS = 0x40
MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_NS = 0x44
MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_SEC_L = 0x48
MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_SEC_H = 0x4C
MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_FNS = 0x50
MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_NS = 0x54
MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_SEC_L = 0x58
MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_SEC_H = 0x5C
MQNIC_QUEUE_BASE_ADDR_REG = 0x00 MQNIC_QUEUE_BASE_ADDR_REG = 0x00
MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG = 0x08 MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG = 0x08
@ -226,6 +283,50 @@ MQNIC_CPL_SIZE = 32
MQNIC_EVENT_SIZE = 32 MQNIC_EVENT_SIZE = 32
class RegBlock(Window):
def __init__(self, parent, offset, size, base=0, **kwargs):
super().__init__(parent, offset, size, base, **kwargs)
self._offset = offset
self.type = 0
self.version = 0
class RegBlockList:
def __init__(self):
self.blocks = []
async def enumerate_reg_blocks(self, window, offset=0):
while True:
rb_type = await window.read_dword(offset+MQNIC_RB_REG_TYPE)
rb_version = await window.read_dword(offset+MQNIC_RB_REG_VER)
rb = window.create_window(offset, window_type=RegBlock)
rb.type = rb_type
rb.version = rb_version
print(f"Block ID {rb_type:#010x} version {rb_version:#010x} at offset {offset:#010x}")
self.blocks.append(rb)
offset = await window.read_dword(offset+MQNIC_RB_REG_NEXT_PTR)
if offset == 0:
return
assert offset & 0x3 == 0, "Register block not aligned"
for block in self.blocks:
assert block.offset != offset, "Register blocks form a loop"
def find(self, rb_type, version=None, index=0):
for block in self.blocks:
if block.type == rb_type and (not version or block.version == version):
if index <= 0:
return block
else:
index -= 1
return None
def __getitem__(self, key):
return self.blocks[key]
def __len__(self):
return len(self.blocks)
class Packet: class Packet:
def __init__(self, data=b''): def __init__(self, data=b''):
self.data = data self.data = data
@ -615,63 +716,76 @@ class RxRing:
await self.write_head_ptr() await self.write_head_ptr()
class Scheduler: class BaseScheduler:
def __init__(self, port, index, hw_regs): def __init__(self, port, index, rb):
self.port = port self.port = port
self.log = port.log self.log = port.log
self.interface = port.interface self.interface = port.interface
self.driver = port.interface.driver self.driver = port.interface.driver
self.rc = port.interface.driver.rc
self.index = index self.index = index
self.hw_regs = hw_regs self.rb = rb
self.hw_regs = None
async def init(self):
pass
class SchedulerRoundRobin(BaseScheduler):
def __init__(self, port, index, rb):
super().__init__(port, index, rb)
async def init(self):
offset = await self.rb.read_dword(MQNIC_RB_SCHED_RR_REG_OFFSET)
self.hw_regs = self.rb.parent.create_window(offset)
class SchedulerControlTdma(BaseScheduler):
def __init__(self, port, index, rb):
super().__init__(port, index, rb)
async def init(self):
offset = await self.rb.read_dword(MQNIC_RB_SCHED_CTRL_TDMA_REG_OFFSET)
self.hw_regs = self.rb.parent.create_window(offset)
class Port: class Port:
def __init__(self, interface, index, hw_regs): def __init__(self, interface, index, rb):
self.interface = interface self.interface = interface
self.log = interface.log self.log = interface.log
self.driver = interface.driver self.driver = interface.driver
self.rc = interface.driver.rc
self.index = index self.index = index
self.hw_regs = hw_regs
self.port_id = None self.block_rb = rb
self.port_features = None self.reg_blocks = RegBlockList()
self.port_mtu = 0
self.sched_count = None self.sched_count = None
self.sched_offset = None
self.sched_stride = None
self.sched_type = None
async def init(self):
# Read ID registers
self.port_id = await self.hw_regs.read_dword(MQNIC_PORT_REG_PORT_ID)
self.log.info("Port ID: 0x%08x", self.port_id)
self.port_features = await self.hw_regs.read_dword(MQNIC_PORT_REG_PORT_FEATURES)
self.log.info("Port features: 0x%08x", self.port_features)
self.port_mtu = await self.hw_regs.read_dword(MQNIC_PORT_REG_PORT_MTU)
self.log.info("Port MTU: %d", self.port_mtu)
self.sched_count = await self.hw_regs.read_dword(MQNIC_PORT_REG_SCHED_COUNT)
self.log.info("Scheduler count: %d", self.sched_count)
self.sched_offset = await self.hw_regs.read_dword(MQNIC_PORT_REG_SCHED_OFFSET)
self.log.info("Scheduler offset: 0x%08x", self.sched_offset)
self.sched_stride = await self.hw_regs.read_dword(MQNIC_PORT_REG_SCHED_STRIDE)
self.log.info("Scheduler stride: 0x%08x", self.sched_stride)
self.sched_type = await self.hw_regs.read_dword(MQNIC_PORT_REG_SCHED_TYPE)
self.log.info("Scheduler type: 0x%08x", self.sched_type)
self.schedulers = [] self.schedulers = []
await self.set_mtu(min(self.port_mtu, 9214)) async def init(self):
# Read ID registers
for k in range(self.sched_count): offset = await self.block_rb.read_dword(MQNIC_RB_SCHED_BLOCK_REG_OFFSET)
p = Scheduler(self, k, self.hw_regs.parent.create_window(self.hw_regs.get_parent_address(0) + self.sched_offset + k*self.sched_stride, self.sched_stride)) await self.reg_blocks.enumerate_reg_blocks(self.block_rb.parent, offset)
self.schedulers.append(p)
async def set_mtu(self, mtu): self.schedulers = []
await self.hw_regs.write_dword(MQNIC_PORT_REG_TX_MTU, mtu)
await self.hw_regs.write_dword(MQNIC_PORT_REG_RX_MTU, mtu) self.sched_count = 0
for rb in self.reg_blocks:
if rb.type == MQNIC_RB_SCHED_RR_TYPE and rb.version == MQNIC_RB_SCHED_RR_VER:
s = SchedulerRoundRobin(self, self.sched_count, rb)
await s.init()
self.schedulers.append(s)
self.sched_count += 1
elif rb.type == MQNIC_RB_SCHED_CTRL_TDMA_TYPE and rb.version == MQNIC_RB_SCHED_CTRL_TDMA_VER:
s = SchedulerControlTdma(self, self.sched_count, rb)
await s.init()
self.schedulers.append(s)
self.sched_count += 1
self.log.info("Scheduler count: %d", self.sched_count)
class Interface: class Interface:
@ -680,23 +794,49 @@ class Interface:
self.log = driver.log self.log = driver.log
self.index = index self.index = index
self.hw_regs = hw_regs self.hw_regs = hw_regs
self.csr_hw_regs = hw_regs.create_window(driver.if_csr_offset, self.hw_regs.size-driver.if_csr_offset) self.csr_hw_regs = hw_regs.create_window(driver.if_csr_offset)
self.port_up = False self.port_up = False
self.if_id = None self.reg_blocks = RegBlockList()
self.event_queue_count = None self.if_ctrl_tx_rb = None
self.if_ctrl_rx_rb = None
self.event_queue_rb = None
self.tx_queue_rb = None
self.tx_cpl_queue_rb = None
self.rx_queue_rb = None
self.rx_cpl_queue_rb = None
self.if_tx_features = None
self.if_rx_features = None
self.max_tx_mtu = 0
self.max_rx_mtu = 0
self.event_queue_offset = None self.event_queue_offset = None
self.tx_queue_count = None self.event_queue_count = None
self.event_queue_stride = None
self.tx_queue_offset = None self.tx_queue_offset = None
self.tx_cpl_queue_count = None self.tx_queue_count = None
self.tx_queue_stride = None
self.tx_cpl_queue_offset = None self.tx_cpl_queue_offset = None
self.rx_queue_count = None self.tx_cpl_queue_count = None
self.tx_cpl_queue_stride = None
self.rx_queue_offset = None self.rx_queue_offset = None
self.rx_cpl_queue_count = None self.rx_queue_count = None
self.rx_queue_stride = None
self.rx_cpl_queue_offset = None self.rx_cpl_queue_offset = None
self.rx_cpl_queue_count = None
self.rx_cpl_queue_stride = None
self.port_count = None self.port_count = None
self.port_offset = None
self.port_stride = None self.event_queues = []
self.tx_queues = []
self.tx_cpl_queues = []
self.rx_queues = []
self.rx_cpl_queues = []
self.ports = []
self.interrupt_running = False self.interrupt_running = False
self.interrupt_pending = 0 self.interrupt_pending = 0
@ -706,45 +846,90 @@ class Interface:
async def init(self): async def init(self):
# Read ID registers # Read ID registers
self.if_id = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_IF_ID)
self.log.info("IF ID: 0x%08x", self.if_id)
self.if_features = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_IF_FEATURES)
self.log.info("IF features: 0x%08x", self.if_features)
self.event_queue_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_EVENT_QUEUE_COUNT) # Enumerate registers
self.log.info("Event queue count: %d", self.event_queue_count) await self.reg_blocks.enumerate_reg_blocks(self.hw_regs, self.driver.if_csr_offset)
self.event_queue_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_EVENT_QUEUE_OFFSET)
self.if_ctrl_tx_rb = self.reg_blocks.find(MQNIC_RB_IF_CTRL_TX_TYPE, MQNIC_RB_IF_CTRL_TX_VER)
self.if_tx_features = await self.if_ctrl_tx_rb.read_dword(MQNIC_RB_IF_CTRL_TX_REG_FEATURES)
self.max_tx_mtu = await self.if_ctrl_tx_rb.read_dword(MQNIC_RB_IF_CTRL_TX_REG_MAX_MTU)
self.log.info("IF TX features: 0x%08x", self.if_tx_features)
self.log.info("Max TX MTU: %d", self.max_tx_mtu)
self.if_ctrl_rx_rb = self.reg_blocks.find(MQNIC_RB_IF_CTRL_RX_TYPE, MQNIC_RB_IF_CTRL_RX_VER)
self.if_rx_features = await self.if_ctrl_rx_rb.read_dword(MQNIC_RB_IF_CTRL_RX_REG_FEATURES)
self.max_rx_mtu = await self.if_ctrl_rx_rb.read_dword(MQNIC_RB_IF_CTRL_TX_REG_MAX_MTU)
self.log.info("IF RX features: 0x%08x", self.if_rx_features)
self.log.info("Max RX MTU: %d", self.max_rx_mtu)
await self.set_mtu(min(self.max_tx_mtu, self.max_rx_mtu, 9214))
self.event_queue_rb = self.reg_blocks.find(MQNIC_RB_EVENT_QM_TYPE, MQNIC_RB_EVENT_QM_VER)
self.event_queue_offset = await self.event_queue_rb.read_dword(MQNIC_RB_EVENT_QM_REG_OFFSET)
self.event_queue_count = await self.event_queue_rb.read_dword(MQNIC_RB_EVENT_QM_REG_COUNT)
self.event_queue_stride = await self.event_queue_rb.read_dword(MQNIC_RB_EVENT_QM_REG_STRIDE)
self.log.info("Event queue offset: 0x%08x", self.event_queue_offset) self.log.info("Event queue offset: 0x%08x", self.event_queue_offset)
self.tx_queue_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_TX_QUEUE_COUNT) self.log.info("Event queue count: %d", self.event_queue_count)
self.log.info("TX queue count: %d", self.tx_queue_count) self.log.info("Event queue stride: 0x%08x", self.event_queue_stride)
self.tx_queue_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_TX_QUEUE_OFFSET)
self.log.info("TX queue offset: 0x%08x", self.tx_queue_offset)
self.tx_cpl_queue_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_TX_CPL_QUEUE_COUNT)
self.log.info("TX completion queue count: %d", self.tx_cpl_queue_count)
self.tx_cpl_queue_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_TX_CPL_QUEUE_OFFSET)
self.log.info("TX completion queue offset: 0x%08x", self.tx_cpl_queue_offset)
self.rx_queue_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_RX_QUEUE_COUNT)
self.log.info("RX queue count: %d", self.rx_queue_count)
self.rx_queue_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_RX_QUEUE_OFFSET)
self.log.info("RX queue offset: 0x%08x", self.rx_queue_offset)
self.rx_cpl_queue_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_RX_CPL_QUEUE_COUNT)
self.log.info("RX completion queue count: %d", self.rx_cpl_queue_count)
self.rx_cpl_queue_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_RX_CPL_QUEUE_OFFSET)
self.log.info("RX completion queue offset: 0x%08x", self.rx_cpl_queue_offset)
self.port_count = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_PORT_COUNT)
self.log.info("Port count: %d", self.port_count)
self.port_offset = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_PORT_OFFSET)
self.log.info("Port offset: 0x%08x", self.port_offset)
self.port_stride = await self.csr_hw_regs.read_dword(MQNIC_IF_REG_PORT_STRIDE)
self.log.info("Port stride: 0x%08x", self.port_stride)
self.event_queue_count = min(self.event_queue_count, MQNIC_MAX_EVENT_RINGS) self.event_queue_count = min(self.event_queue_count, MQNIC_MAX_EVENT_RINGS)
self.tx_queue_rb = self.reg_blocks.find(MQNIC_RB_TX_QM_TYPE, MQNIC_RB_TX_QM_VER)
self.tx_queue_offset = await self.tx_queue_rb.read_dword(MQNIC_RB_TX_QM_REG_OFFSET)
self.tx_queue_count = await self.tx_queue_rb.read_dword(MQNIC_RB_TX_QM_REG_COUNT)
self.tx_queue_stride = await self.tx_queue_rb.read_dword(MQNIC_RB_TX_QM_REG_STRIDE)
self.log.info("TX queue offset: 0x%08x", self.tx_queue_offset)
self.log.info("TX queue count: %d", self.tx_queue_count)
self.log.info("TX queue stride: 0x%08x", self.tx_queue_stride)
self.tx_queue_count = min(self.tx_queue_count, MQNIC_MAX_TX_RINGS) self.tx_queue_count = min(self.tx_queue_count, MQNIC_MAX_TX_RINGS)
self.tx_cpl_queue_rb = self.reg_blocks.find(MQNIC_RB_TX_CQM_TYPE, MQNIC_RB_TX_CQM_VER)
self.tx_cpl_queue_offset = await self.tx_cpl_queue_rb.read_dword(MQNIC_RB_TX_CQM_REG_OFFSET)
self.tx_cpl_queue_count = await self.tx_cpl_queue_rb.read_dword(MQNIC_RB_TX_CQM_REG_COUNT)
self.tx_cpl_queue_stride = await self.tx_cpl_queue_rb.read_dword(MQNIC_RB_TX_CQM_REG_STRIDE)
self.log.info("TX completion queue offset: 0x%08x", self.tx_cpl_queue_offset)
self.log.info("TX completion queue count: %d", self.tx_cpl_queue_count)
self.log.info("TX completion queue stride: 0x%08x", self.tx_cpl_queue_stride)
self.tx_cpl_queue_count = min(self.tx_cpl_queue_count, MQNIC_MAX_TX_CPL_RINGS) self.tx_cpl_queue_count = min(self.tx_cpl_queue_count, MQNIC_MAX_TX_CPL_RINGS)
self.rx_queue_rb = self.reg_blocks.find(MQNIC_RB_RX_QM_TYPE, MQNIC_RB_RX_QM_VER)
self.rx_queue_offset = await self.rx_queue_rb.read_dword(MQNIC_RB_RX_QM_REG_OFFSET)
self.rx_queue_count = await self.rx_queue_rb.read_dword(MQNIC_RB_RX_QM_REG_COUNT)
self.rx_queue_stride = await self.rx_queue_rb.read_dword(MQNIC_RB_RX_QM_REG_STRIDE)
self.log.info("RX queue offset: 0x%08x", self.rx_queue_offset)
self.log.info("RX queue count: %d", self.rx_queue_count)
self.log.info("RX queue stride: 0x%08x", self.rx_queue_stride)
self.rx_queue_count = min(self.rx_queue_count, MQNIC_MAX_RX_RINGS) self.rx_queue_count = min(self.rx_queue_count, MQNIC_MAX_RX_RINGS)
self.rx_cpl_queue_rb = self.reg_blocks.find(MQNIC_RB_RX_CQM_TYPE, MQNIC_RB_RX_CQM_VER)
self.rx_cpl_queue_offset = await self.rx_cpl_queue_rb.read_dword(MQNIC_RB_RX_CQM_REG_OFFSET)
self.rx_cpl_queue_count = await self.rx_cpl_queue_rb.read_dword(MQNIC_RB_RX_CQM_REG_COUNT)
self.rx_cpl_queue_stride = await self.rx_cpl_queue_rb.read_dword(MQNIC_RB_RX_CQM_REG_STRIDE)
self.log.info("RX completion queue offset: 0x%08x", self.rx_cpl_queue_offset)
self.log.info("RX completion queue count: %d", self.rx_cpl_queue_count)
self.log.info("RX completion queue stride: 0x%08x", self.rx_cpl_queue_stride)
self.rx_cpl_queue_count = min(self.rx_cpl_queue_count, MQNIC_MAX_RX_CPL_RINGS) self.rx_cpl_queue_count = min(self.rx_cpl_queue_count, MQNIC_MAX_RX_CPL_RINGS)
self.event_queues = [] self.event_queues = []
self.tx_queues = [] self.tx_queues = []
self.tx_cpl_queues = [] self.tx_cpl_queues = []
self.rx_queues = [] self.rx_queues = []
@ -753,39 +938,48 @@ class Interface:
for k in range(self.event_queue_count): for k in range(self.event_queue_count):
q = EqRing(self, 1024, MQNIC_EVENT_SIZE, self.index, q = EqRing(self, 1024, MQNIC_EVENT_SIZE, self.index,
self.hw_regs.create_window(self.event_queue_offset + k*MQNIC_EVENT_QUEUE_STRIDE, MQNIC_EVENT_QUEUE_STRIDE)) self.hw_regs.create_window(self.event_queue_offset + k*self.event_queue_stride, self.event_queue_stride))
await q.init() await q.init()
self.event_queues.append(q) self.event_queues.append(q)
for k in range(self.tx_queue_count): for k in range(self.tx_queue_count):
q = TxRing(self, 1024, MQNIC_DESC_SIZE*4, k, q = TxRing(self, 1024, MQNIC_DESC_SIZE*4, k,
self.hw_regs.create_window(self.tx_queue_offset + k*MQNIC_QUEUE_STRIDE, MQNIC_QUEUE_STRIDE)) self.hw_regs.create_window(self.tx_queue_offset + k*self.tx_queue_stride, self.tx_queue_stride))
await q.init() await q.init()
self.tx_queues.append(q) self.tx_queues.append(q)
for k in range(self.tx_cpl_queue_count): for k in range(self.tx_cpl_queue_count):
q = CqRing(self, 1024, MQNIC_CPL_SIZE, k, q = CqRing(self, 1024, MQNIC_CPL_SIZE, k,
self.hw_regs.create_window(self.tx_cpl_queue_offset + k*MQNIC_CPL_QUEUE_STRIDE, MQNIC_CPL_QUEUE_STRIDE)) self.hw_regs.create_window(self.tx_cpl_queue_offset + k*self.tx_cpl_queue_stride, self.tx_cpl_queue_stride))
await q.init() await q.init()
self.tx_cpl_queues.append(q) self.tx_cpl_queues.append(q)
for k in range(self.rx_queue_count): for k in range(self.rx_queue_count):
q = RxRing(self, 1024, MQNIC_DESC_SIZE*4, k, q = RxRing(self, 1024, MQNIC_DESC_SIZE*4, k,
self.hw_regs.create_window(self.rx_queue_offset + k*MQNIC_QUEUE_STRIDE, MQNIC_QUEUE_STRIDE)) self.hw_regs.create_window(self.rx_queue_offset + k*self.rx_queue_stride, self.rx_queue_stride))
await q.init() await q.init()
self.rx_queues.append(q) self.rx_queues.append(q)
for k in range(self.rx_cpl_queue_count): for k in range(self.rx_cpl_queue_count):
q = CqRing(self, 1024, MQNIC_CPL_SIZE, k, q = CqRing(self, 1024, MQNIC_CPL_SIZE, k,
self.hw_regs.create_window(self.rx_cpl_queue_offset + k*MQNIC_CPL_QUEUE_STRIDE, MQNIC_CPL_QUEUE_STRIDE)) self.hw_regs.create_window(self.rx_cpl_queue_offset + k*self.rx_cpl_queue_stride, self.rx_cpl_queue_stride))
await q.init() await q.init()
self.rx_cpl_queues.append(q) self.rx_cpl_queues.append(q)
for k in range(self.port_count): self.port_count = 0
p = Port(self, k, self.hw_regs.create_window(self.port_offset + k*self.port_stride, self.port_stride)) while True:
rb = self.reg_blocks.find(MQNIC_RB_SCHED_BLOCK_TYPE, MQNIC_RB_SCHED_BLOCK_VER, index=self.port_count)
if not rb:
break
p = Port(self, self.port_count, rb)
await p.init() await p.init()
self.ports.append(p) self.ports.append(p)
self.port_count += 1
self.log.info("Port count: %d", self.port_count)
# wait for all writes to complete # wait for all writes to complete
await self.hw_regs.read_dword(0) await self.hw_regs.read_dword(0)
@ -1020,8 +1214,11 @@ class Interface:
await ring.write_head_ptr() await ring.write_head_ptr()
async def set_mtu(self, mtu): async def set_mtu(self, mtu):
for p in self.ports: await self.if_ctrl_tx_rb.write_dword(MQNIC_RB_IF_CTRL_TX_REG_MTU, mtu)
await p.set_mtu(mtu) await self.if_ctrl_rx_rb.write_dword(MQNIC_RB_IF_CTRL_RX_REG_MTU, mtu)
async def set_rss_mask(self, mask):
await self.if_ctrl_rx_rb.write_dword(MQNIC_RB_IF_CTRL_RX_REG_RSS_MASK, mask)
async def recv(self): async def recv(self):
if not self.pkt_rx_queue: if not self.pkt_rx_queue:
@ -1087,13 +1284,22 @@ class Driver:
self.irq_sig = None self.irq_sig = None
self.irq_list = [] self.irq_list = []
self.reg_blocks = RegBlockList()
self.fw_id_rb = None
self.if_rb = None
self.phc_rb = None
self.fpga_id = None
self.fw_id = None self.fw_id = None
self.fw_ver = None self.fw_ver = None
self.board_id = None self.board_id = None
self.board_ver = None self.board_ver = None
self.phc_count = None self.build_date = None
self.phc_offset = None self.build_time = None
self.phc_hw_addr = None self.git_hash = None
self.rel_info = None
self.if_offset = None
self.if_count = None self.if_count = None
self.if_stride = None self.if_stride = None
self.if_csr_offset = None self.if_csr_offset = None
@ -1154,35 +1360,53 @@ class Driver:
if self.ram_hw_regs: if self.ram_hw_regs:
self.log.info("RAM BAR size: %d", self.ram_hw_regs.size) self.log.info("RAM BAR size: %d", self.ram_hw_regs.size)
# Enumerate registers
await self.reg_blocks.enumerate_reg_blocks(self.hw_regs)
# Read ID registers # Read ID registers
self.fw_id = await self.hw_regs.read_dword(MQNIC_REG_FW_ID) self.fw_id_rb = self.reg_blocks.find(MQNIC_RB_FW_ID_TYPE, MQNIC_RB_FW_ID_VER)
self.fpga_id = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_FPGA_ID)
self.log.info("FPGA JTAG ID: 0x%08x", self.fpga_id)
self.fw_id = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_FW_ID)
self.log.info("FW ID: 0x%08x", self.fw_id) self.log.info("FW ID: 0x%08x", self.fw_id)
self.fw_ver = await self.hw_regs.read_dword(MQNIC_REG_FW_VER) self.fw_ver = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_FW_VER)
self.log.info("FW version: %d.%d", self.fw_ver >> 16, self.fw_ver & 0xffff) self.log.info("FW version: %d.%d.%d.%d", *self.fw_ver.to_bytes(4, 'big'))
self.board_id = await self.hw_regs.read_dword(MQNIC_REG_BOARD_ID) self.board_id = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_BOARD_ID)
self.log.info("Board ID: 0x%08x", self.board_id) self.log.info("Board ID: 0x%08x", self.board_id)
self.board_ver = await self.hw_regs.read_dword(MQNIC_REG_BOARD_VER) self.board_ver = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_BOARD_VER)
self.log.info("Board version: %d.%d", self.board_ver >> 16, self.board_ver & 0xffff) self.log.info("Board version: %d.%d.%d.%d", *self.board_ver.to_bytes(4, 'big'))
self.build_date = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_BUILD_DATE)
self.log.info("Build date: %s UTC (raw: 0x%08x)", datetime.datetime.utcfromtimestamp(self.build_date).isoformat(' '), self.build_date)
self.git_hash = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_GIT_HASH)
self.log.info("Git hash: %08x", self.git_hash)
self.rel_info = await self.fw_id_rb.read_dword(MQNIC_RB_FW_ID_REG_REL_INFO)
self.log.info("Release info: %d", self.rel_info)
self.phc_count = await self.hw_regs.read_dword(MQNIC_REG_PHC_COUNT) self.phc_rb = self.reg_blocks.find(MQNIC_RB_PHC_TYPE, MQNIC_RB_PHC_VER)
self.log.info("PHC count: %d", self.phc_count)
self.phc_offset = await self.hw_regs.read_dword(MQNIC_REG_PHC_OFFSET)
self.log.info("PHC offset: 0x%08x", self.phc_offset)
self.if_count = await self.hw_regs.read_dword(MQNIC_REG_IF_COUNT)
self.log.info("IF count: %d", self.if_count)
self.if_stride = await self.hw_regs.read_dword(MQNIC_REG_IF_STRIDE)
self.log.info("IF stride: 0x%08x", self.if_stride)
self.if_csr_offset = await self.hw_regs.read_dword(MQNIC_REG_IF_CSR_OFFSET)
self.log.info("IF CSR offset: 0x%08x", self.if_csr_offset)
# Enumerate interfaces
self.if_rb = self.reg_blocks.find(MQNIC_RB_IF_TYPE, MQNIC_RB_IF_VER)
self.interfaces = [] self.interfaces = []
if self.if_rb:
self.if_offset = await self.if_rb.read_dword(MQNIC_RB_IF_REG_OFFSET)
self.log.info("IF offset: %d", self.if_offset)
self.if_count = await self.if_rb.read_dword(MQNIC_RB_IF_REG_COUNT)
self.log.info("IF count: %d", self.if_count)
self.if_stride = await self.if_rb.read_dword(MQNIC_RB_IF_REG_STRIDE)
self.log.info("IF stride: 0x%08x", self.if_stride)
self.if_csr_offset = await self.if_rb.read_dword(MQNIC_RB_IF_REG_CSR_OFFSET)
self.log.info("IF CSR offset: 0x%08x", self.if_csr_offset)
for k in range(self.if_count): for k in range(self.if_count):
i = Interface(self, k, self.hw_regs.create_window(k*self.if_stride, self.if_stride)) i = Interface(self, k, self.hw_regs.create_window(self.if_offset + k*self.if_stride, self.if_stride))
await i.init() await i.init()
self.interfaces.append(i) self.interfaces.append(i)
else:
self.log.warning("No interface block found")
async def _run_edge_interrupts(self, signal): async def _run_edge_interrupts(self, signal):
last_val = 0 last_val = 0
count = len(signal) count = len(signal)

View File

@ -193,7 +193,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
for interface in tb.driver.interfaces: for interface in tb.driver.interfaces:
await interface.ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await interface.ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(interface.tx_queue_count): for k in range(interface.tx_queue_count):
await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -327,7 +327,7 @@ async def run_test_nic(dut):
tb.log.info("All interface 0 ports") tb.log.info("All interface 0 ports")
for port in tb.driver.interfaces[0].ports: for port in tb.driver.interfaces[0].ports:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(port.interface.tx_queue_count): for k in range(port.interface.tx_queue_count):
if k % len(tb.driver.interfaces[0].ports) == port.index: if k % len(tb.driver.interfaces[0].ports) == port.index:
await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -353,7 +353,7 @@ async def run_test_nic(dut):
tb.loopback_enable = False tb.loopback_enable = False
for port in tb.driver.interfaces[0].ports[1:]: for port in tb.driver.interfaces[0].ports[1:]:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000000) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000)
tb.log.info("Read statistics counters") tb.log.info("Read statistics counters")

View File

@ -304,7 +304,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
for interface in tb.driver.interfaces: for interface in tb.driver.interfaces:
await interface.ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await interface.ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(interface.tx_queue_count): for k in range(interface.tx_queue_count):
await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -438,7 +438,7 @@ async def run_test_nic(dut):
tb.log.info("All interface 0 ports") tb.log.info("All interface 0 ports")
for port in tb.driver.interfaces[0].ports: for port in tb.driver.interfaces[0].ports:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(port.interface.tx_queue_count): for k in range(port.interface.tx_queue_count):
if k % len(tb.driver.interfaces[0].ports) == port.index: if k % len(tb.driver.interfaces[0].ports) == port.index:
await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -464,7 +464,7 @@ async def run_test_nic(dut):
tb.loopback_enable = False tb.loopback_enable = False
for port in tb.driver.interfaces[0].ports[1:]: for port in tb.driver.interfaces[0].ports[1:]:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000000) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000)
tb.log.info("Read statistics counters") tb.log.info("Read statistics counters")

View File

@ -379,7 +379,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
for interface in tb.driver.interfaces: for interface in tb.driver.interfaces:
await interface.ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await interface.ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(interface.tx_queue_count): for k in range(interface.tx_queue_count):
await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -513,7 +513,7 @@ async def run_test_nic(dut):
tb.log.info("All interface 0 ports") tb.log.info("All interface 0 ports")
for port in tb.driver.interfaces[0].ports: for port in tb.driver.interfaces[0].ports:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(port.interface.tx_queue_count): for k in range(port.interface.tx_queue_count):
if k % len(tb.driver.interfaces[0].ports) == port.index: if k % len(tb.driver.interfaces[0].ports) == port.index:
await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -539,7 +539,7 @@ async def run_test_nic(dut):
tb.loopback_enable = False tb.loopback_enable = False
for port in tb.driver.interfaces[0].ports[1:]: for port in tb.driver.interfaces[0].ports[1:]:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000000) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000)
tb.log.info("Read statistics counters") tb.log.info("Read statistics counters")

View File

@ -379,7 +379,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
for interface in tb.driver.interfaces: for interface in tb.driver.interfaces:
await interface.ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await interface.ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(interface.tx_queue_count): for k in range(interface.tx_queue_count):
await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await interface.ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -513,7 +513,7 @@ async def run_test_nic(dut):
tb.log.info("All interface 0 ports") tb.log.info("All interface 0 ports")
for port in tb.driver.interfaces[0].ports: for port in tb.driver.interfaces[0].ports:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(port.interface.tx_queue_count): for k in range(port.interface.tx_queue_count):
if k % len(tb.driver.interfaces[0].ports) == port.index: if k % len(tb.driver.interfaces[0].ports) == port.index:
await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await port.schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
@ -539,7 +539,7 @@ async def run_test_nic(dut):
tb.loopback_enable = False tb.loopback_enable = False
for port in tb.driver.interfaces[0].ports[1:]: for port in tb.driver.interfaces[0].ports[1:]:
await port.hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000000) await port.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000)
await Timer(1000, 'ns') await Timer(1000, 'ns')
@ -552,22 +552,23 @@ async def run_test_nic(dut):
tb.loopback_enable = True tb.loopback_enable = True
# configure TDMA scheduler # configure TDMA scheduler
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) tdma_sch_rb = tb.driver.interfaces[0].ports[0].reg_blocks.find(mqnic.MQNIC_RB_TDMA_SCH_TYPE, mqnic.MQNIC_RB_TDMA_SCH_VER, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_FNS, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_NS, 40000)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_SEC_L, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_SCH_PERIOD_SEC_H, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_FNS, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_NS, 10000)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_SEC_L, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_TS_PERIOD_SEC_H, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_FNS, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_NS, 5000)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_SEC_L, 0)
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_ACTIVE_PERIOD_SEC_H, 0)
await tdma_sch_rb.write_dword(mqnic.MQNIC_RB_TDMA_SCH_REG_CTRL, 0x00000001)
# enable queues with global enable off # enable queues with global enable off
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000001)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1655,11 +1658,14 @@ assign front_led[1] = qsfp_1_rx_status;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -369,6 +372,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -464,13 +470,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -482,8 +489,9 @@ always @(posedge clk_250mhz) begin
qsfp_1_sel_reg <= ctrl_reg_wr_data[17]; qsfp_1_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -491,8 +499,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_reset_reg <= ctrl_reg_wr_data[4]; qsfp_reset_reg <= ctrl_reg_wr_data[4];
end end
@ -500,9 +509,13 @@ always @(posedge clk_250mhz) begin
qsfp_reset_reg <= ctrl_reg_wr_data[12]; qsfp_reset_reg <= ctrl_reg_wr_data[12];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h3C: begin
// QSPI 0 control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -514,8 +527,8 @@ always @(posedge clk_250mhz) begin
qspi_0_cs_reg <= ctrl_reg_wr_data[17]; qspi_0_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -535,10 +548,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i;
@ -546,15 +561,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg; ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg;
ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg; ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l; ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l;
ctrl_reg_rd_data_reg[1] <= !qsfp_int_l; ctrl_reg_rd_data_reg[1] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg;
@ -562,23 +585,26 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[9] <= !qsfp_int_l; ctrl_reg_rd_data_reg[9] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI) ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h40: begin
// QSPI 0 control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_0_cs; ctrl_reg_rd_data_reg[17] <= qspi_0_cs;
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
@ -759,10 +785,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -866,6 +896,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -376,7 +376,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1429,11 +1432,14 @@ qsfp_1_phy_3_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -409,6 +412,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -525,13 +531,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -543,8 +550,9 @@ always @(posedge clk_250mhz) begin
qsfp_1_sel_reg <= ctrl_reg_wr_data[17]; qsfp_1_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -552,8 +560,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_reset_reg <= ctrl_reg_wr_data[4]; qsfp_reset_reg <= ctrl_reg_wr_data[4];
end end
@ -561,9 +570,13 @@ always @(posedge clk_250mhz) begin
qsfp_reset_reg <= ctrl_reg_wr_data[12]; qsfp_reset_reg <= ctrl_reg_wr_data[12];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h3C: begin
// QSPI 0 control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -575,8 +588,8 @@ always @(posedge clk_250mhz) begin
qspi_0_cs_reg <= ctrl_reg_wr_data[17]; qspi_0_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -596,10 +609,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i;
@ -607,15 +622,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg; ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg;
ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg; ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l; ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l;
ctrl_reg_rd_data_reg[1] <= !qsfp_int_l; ctrl_reg_rd_data_reg[1] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg;
@ -623,23 +646,26 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[9] <= !qsfp_int_l; ctrl_reg_rd_data_reg[9] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI) ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h40: begin
// QSPI 0 control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_0_cs; ctrl_reg_rd_data_reg[17] <= qspi_0_cs;
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
@ -1006,10 +1032,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1113,6 +1143,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -438,7 +438,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B39093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h41449003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x4144]
dict set params FPGA_ID "32'h4B39093" set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1453,11 +1456,14 @@ qsfp_1_phy_3_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h4144, 16'h9003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B39093, parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -409,6 +412,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -525,13 +531,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; qsfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -543,8 +550,9 @@ always @(posedge clk_250mhz) begin
qsfp_1_sel_reg <= ctrl_reg_wr_data[17]; qsfp_1_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -552,8 +560,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_reset_reg <= ctrl_reg_wr_data[4]; qsfp_reset_reg <= ctrl_reg_wr_data[4];
end end
@ -561,9 +570,13 @@ always @(posedge clk_250mhz) begin
qsfp_reset_reg <= ctrl_reg_wr_data[12]; qsfp_reset_reg <= ctrl_reg_wr_data[12];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h3C: begin
// QSPI 0 control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -575,8 +588,8 @@ always @(posedge clk_250mhz) begin
qspi_0_cs_reg <= ctrl_reg_wr_data[17]; qspi_0_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -596,10 +609,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= qsfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= qsfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= qsfp_i2c_sda_i;
@ -607,15 +622,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg; ctrl_reg_rd_data_reg[16] <= qsfp_0_sel_reg;
ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg; ctrl_reg_rd_data_reg[17] <= qsfp_1_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l; ctrl_reg_rd_data_reg[0] <= !qsfp_0_modprs_l;
ctrl_reg_rd_data_reg[1] <= !qsfp_int_l; ctrl_reg_rd_data_reg[1] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg;
@ -623,23 +646,26 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[9] <= !qsfp_int_l; ctrl_reg_rd_data_reg[9] <= !qsfp_int_l;
ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp_reset_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI) ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h40: begin
// QSPI 0 control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_0_cs; ctrl_reg_rd_data_reg[17] <= qspi_0_cs;
end end
16'h0148: begin RBB+8'h44: begin
// QSPI 1 control // SPI flash ctrl: control 1
ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
@ -1006,10 +1032,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1113,6 +1143,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -438,7 +438,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B37093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee90c8" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B37093" set board_device_id [expr 0x90c8]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {90c8} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90c8},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B37093, parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1789,11 +1792,14 @@ assign led[2] = qsfp0_rx_status; // green
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90c8},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B37093, parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -386,6 +389,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -496,13 +502,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -510,8 +517,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp0_reset_reg <= ctrl_reg_wr_data[4]; qsfp0_reset_reg <= ctrl_reg_wr_data[4];
qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp0_lpmode_reg <= ctrl_reg_wr_data[5];
@ -521,9 +529,13 @@ always @(posedge clk_250mhz) begin
qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -535,14 +547,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h4C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h50: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -558,17 +572,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; ctrl_reg_rd_data_reg[1] <= !qsfp0_intl;
ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg;
@ -578,24 +598,30 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h48: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h4C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h50: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -767,10 +793,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -874,6 +904,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -376,7 +376,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B37093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee90c8" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B37093" set board_device_id [expr 0x90c8]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {90c8} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90c8},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B37093, parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1576,11 +1579,14 @@ qsfp1_phy_4_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90c8},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B37093, parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -426,6 +429,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -557,13 +563,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -571,8 +578,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp0_reset_reg <= ctrl_reg_wr_data[4]; qsfp0_reset_reg <= ctrl_reg_wr_data[4];
qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp0_lpmode_reg <= ctrl_reg_wr_data[5];
@ -582,9 +590,13 @@ always @(posedge clk_250mhz) begin
qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -596,14 +608,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h4C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h50: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -619,17 +633,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; ctrl_reg_rd_data_reg[1] <= !qsfp0_intl;
ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg;
@ -639,24 +659,30 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h48: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h4C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h50: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -1014,10 +1040,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1121,6 +1151,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -438,7 +438,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B57093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee90fa" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B57093" set board_device_id [expr 0x90fa]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {90fa} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90fa},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B57093, parameter FPGA_ID = 32'h4B57093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90fa,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1789,11 +1792,14 @@ assign led[2] = qsfp0_rx_status; // green
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90fa},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B57093, parameter FPGA_ID = 32'h4B57093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90fa,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -386,6 +389,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -496,13 +502,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -510,8 +517,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp0_reset_reg <= ctrl_reg_wr_data[4]; qsfp0_reset_reg <= ctrl_reg_wr_data[4];
qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp0_lpmode_reg <= ctrl_reg_wr_data[5];
@ -521,9 +529,13 @@ always @(posedge clk_250mhz) begin
qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -535,14 +547,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h4C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h50: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -558,17 +572,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; ctrl_reg_rd_data_reg[1] <= !qsfp0_intl;
ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg;
@ -578,24 +598,30 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h48: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h4C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h50: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -767,10 +793,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -874,6 +904,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -376,7 +376,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B57093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee90fa" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B57093" set board_device_id [expr 0x90fa]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {90fa} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90fa},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B57093, parameter FPGA_ID = 32'h4B57093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90fa,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1576,11 +1579,14 @@ qsfp1_phy_4_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h90fa},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B57093, parameter FPGA_ID = 32'h4B57093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_90fa,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -426,6 +429,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -557,13 +563,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -571,8 +578,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp0_reset_reg <= ctrl_reg_wr_data[4]; qsfp0_reset_reg <= ctrl_reg_wr_data[4];
qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp0_lpmode_reg <= ctrl_reg_wr_data[5];
@ -582,9 +590,13 @@ always @(posedge clk_250mhz) begin
qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -596,14 +608,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h4C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h50: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -619,17 +633,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; ctrl_reg_rd_data_reg[1] <= !qsfp0_intl;
ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg;
@ -639,24 +659,30 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h48: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h4C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h50: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -1014,10 +1040,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1121,6 +1151,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -438,7 +438,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B7D093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9118" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B7D093" set board_device_id [expr 0x9118]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4c_uscale_plus_0] set pcie [get_ips pcie4c_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9118} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9118},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B7D093, parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9118,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1686,11 +1689,14 @@ qsfp1_cmac_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9118},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B7D093, parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9118,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -358,6 +361,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -445,13 +451,18 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h0C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h10: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -463,14 +474,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h2C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h30: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -486,25 +499,30 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // QSPI flash
// Flash RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
16'h0140: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
// Flash ID RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // SPI flash ctrl: Next header
RBB+8'h0C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h10: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h2C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h30: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -651,10 +669,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -758,6 +780,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -365,7 +365,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B7D093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9118" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B7D093" set board_device_id [expr 0x9118]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4c_uscale_plus_0] set pcie [get_ips pcie4c_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9118} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9118},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B7D093, parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9118,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1479,11 +1482,14 @@ qsfp1_phy_4_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9118},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B7D093, parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9118,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -398,6 +401,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -506,13 +512,18 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h0C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h10: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -524,14 +535,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h2C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h30: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -547,25 +560,30 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // QSPI flash
// Flash RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
16'h0140: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
// Flash ID RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // SPI flash ctrl: Next header
RBB+8'h0C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h10: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h2C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h30: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -898,10 +916,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1005,6 +1027,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -427,7 +427,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B77093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9032" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B77093" set board_device_id [expr 0x9032]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -140,12 +183,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4c_uscale_plus_0] set pcie [get_ips pcie4c_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9032} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9032},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B77093, parameter FPGA_ID = 32'h4B77093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9032,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -1288,11 +1291,14 @@ assign qsfp_led_stat_g = qsfp_rx_status;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9032},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B77093, parameter FPGA_ID = 32'h4B77093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9032,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -337,6 +340,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 1) begin if (PORT_COUNT > 1) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -424,13 +430,18 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h0C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h10: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -442,14 +453,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h2C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h30: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -465,25 +478,30 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // QSPI flash
// Flash RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
16'h0140: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
// Flash ID RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // SPI flash ctrl: Next header
RBB+8'h0C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h10: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h2C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h30: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -606,10 +624,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -713,6 +735,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -338,7 +338,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B77093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9032" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B77093" set board_device_id [expr 0x9032]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -147,12 +190,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4c_uscale_plus_0] set pcie [get_ips pcie4c_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9032} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9032},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B77093, parameter FPGA_ID = 32'h4B77093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9032,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -1195,11 +1198,14 @@ qsfp_phy_4_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9032},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B77093, parameter FPGA_ID = 32'h4B77093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9032,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -360,6 +363,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 4) begin if (PORT_COUNT > 4) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -468,13 +474,18 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h0C: begin
// QSPI control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h10: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -486,14 +497,16 @@ always @(posedge clk_250mhz) begin
qspi_cs_reg <= ctrl_reg_wr_data[17]; qspi_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
// BMC // Alveo BMC
16'h0180: begin RBB+8'h2C: begin
// BMC ctrl: Addr
if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin if (!m_axil_cms_arvalid && !m_axil_cms_awvalid) begin
m_axil_cms_addr_reg <= ctrl_reg_wr_data; m_axil_cms_addr_reg <= ctrl_reg_wr_data;
m_axil_cms_arvalid_reg <= 1'b1; m_axil_cms_arvalid_reg <= 1'b1;
end end
end end
16'h0184: begin RBB+8'h30: begin
// BMC ctrl: Data
if (!m_axil_cms_wvalid) begin if (!m_axil_cms_wvalid) begin
m_axil_cms_awvalid_reg <= 1'b1; m_axil_cms_awvalid_reg <= 1'b1;
m_axil_cms_wdata_reg <= ctrl_reg_wr_data; m_axil_cms_wdata_reg <= ctrl_reg_wr_data;
@ -509,25 +522,30 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // QSPI flash
// Flash RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
16'h0140: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
// Flash ID RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // SPI flash ctrl: Next header
RBB+8'h0C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo) ctrl_reg_rd_data_reg[15:8] <= 8'h81; // configuration (Alveo)
ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h10: begin
// QSPI control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_cs; ctrl_reg_rd_data_reg[17] <= qspi_cs;
end end
// BMC // Alveo BMC
16'h0180: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C140; // BMC ctrl: Type
16'h0184: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // BMC ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // BMC ctrl: Next header
RBB+8'h2C: ctrl_reg_rd_data_reg <= m_axil_cms_addr_reg; // BMC ctrl: Addr
RBB+8'h30: ctrl_reg_rd_data_reg <= m_axil_cms_rdata; // BMC ctrl: Data
default: ctrl_reg_rd_ack_reg <= 1'b0; default: ctrl_reg_rd_ack_reg <= 1'b0;
endcase endcase
end end
@ -801,10 +819,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -908,6 +930,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -369,7 +369,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x3823093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h1ce40003" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x1ce4]
dict set params FPGA_ID "32'h3823093" set board_device_id [expr 0x0003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "10"
set pcie [get_ips pcie3_ultrascale_0] set pcie [get_ips pcie3_ultrascale_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {0003} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3823093, parameter FPGA_ID = 32'h3823093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -992,11 +995,14 @@ assign sfp_2_led[1] = 1'b0;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0003},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3823093, parameter FPGA_ID = 32'h3823093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0003,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -342,6 +345,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -446,13 +452,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -464,8 +471,9 @@ always @(posedge clk_250mhz) begin
sfp_2_sel_reg <= ctrl_reg_wr_data[17]; sfp_2_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -473,8 +481,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5]; sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5];
sfp_1_rs_reg <= ctrl_reg_wr_data[6]; sfp_1_rs_reg <= ctrl_reg_wr_data[6];
@ -484,15 +493,19 @@ always @(posedge clk_250mhz) begin
sfp_2_rs_reg <= ctrl_reg_wr_data[14]; sfp_2_rs_reg <= ctrl_reg_wr_data[14];
end end
end end
// Flash // BPI flash
16'h0144: begin RBB+8'h3C: begin
// Flash address // BPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// BPI flash ctrl: address
flash_addr_reg <= ctrl_reg_wr_data[22:0]; flash_addr_reg <= ctrl_reg_wr_data[22:0];
flash_region_reg <= ctrl_reg_wr_data[23]; flash_region_reg <= ctrl_reg_wr_data[23];
end end
16'h0148: flash_dq_o_reg <= ctrl_reg_wr_data; // Flash data RBB+8'h44: flash_dq_o_reg <= ctrl_reg_wr_data; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
flash_ce_n_reg <= ctrl_reg_wr_data[0]; flash_ce_n_reg <= ctrl_reg_wr_data[0];
flash_oe_n_reg <= ctrl_reg_wr_data[1]; flash_oe_n_reg <= ctrl_reg_wr_data[1];
@ -514,10 +527,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg); ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg);
@ -525,15 +540,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg; ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg;
ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg; ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !sfp_1_npres; ctrl_reg_rd_data_reg[0] <= !sfp_1_npres;
ctrl_reg_rd_data_reg[2] <= sfp_1_los; ctrl_reg_rd_data_reg[2] <= sfp_1_los;
ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg; ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg;
@ -543,22 +566,25 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg; ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg;
ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg; ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg;
end end
// Flash // BPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C121; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// BPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI) ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 16; // data width ctrl_reg_rd_data_reg[23:16] <= 16; // data width
ctrl_reg_rd_data_reg[31:24] <= 24; // address width ctrl_reg_rd_data_reg[31:24] <= 24; // address width
end end
16'h0144: begin RBB+8'h40: begin
// Flash address // BPI flash ctrl: address
ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg; ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg;
ctrl_reg_rd_data_reg[23] <= flash_region_reg; ctrl_reg_rd_data_reg[23] <= flash_region_reg;
end end
16'h0148: ctrl_reg_rd_data_reg <= flash_dq_i; // Flash data RBB+8'h44: ctrl_reg_rd_data_reg <= flash_dq_i; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted) ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted)
ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted) ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted)
ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted) ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted)
@ -774,10 +800,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -881,6 +911,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -345,7 +345,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4A63093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h1ce40009" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x1ce4]
dict set params FPGA_ID "32'h4A63093" set board_device_id [expr 0x0009]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {0009} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0009},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4A63093, parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0009,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1029,11 +1032,14 @@ assign sfp_2_led[1] = 1'b0;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0009},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4A63093, parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0009,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -350,6 +353,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -475,13 +481,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -493,8 +500,9 @@ always @(posedge clk_250mhz) begin
sfp_2_sel_reg <= ctrl_reg_wr_data[17]; sfp_2_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -502,8 +510,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5]; sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5];
sfp_1_rs_reg <= ctrl_reg_wr_data[6]; sfp_1_rs_reg <= ctrl_reg_wr_data[6];
@ -513,15 +522,19 @@ always @(posedge clk_250mhz) begin
sfp_2_rs_reg <= ctrl_reg_wr_data[14]; sfp_2_rs_reg <= ctrl_reg_wr_data[14];
end end
end end
// Flash // BPI flash
16'h0144: begin RBB+8'h3C: begin
// Flash address // BPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// BPI flash ctrl: address
flash_addr_reg <= ctrl_reg_wr_data[22:0]; flash_addr_reg <= ctrl_reg_wr_data[22:0];
flash_region_reg <= ctrl_reg_wr_data[23]; flash_region_reg <= ctrl_reg_wr_data[23];
end end
16'h0148: flash_dq_o_reg <= ctrl_reg_wr_data; // Flash data RBB+8'h44: flash_dq_o_reg <= ctrl_reg_wr_data; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
flash_ce_n_reg <= ctrl_reg_wr_data[0]; flash_ce_n_reg <= ctrl_reg_wr_data[0];
flash_oe_n_reg <= ctrl_reg_wr_data[1]; flash_oe_n_reg <= ctrl_reg_wr_data[1];
@ -543,10 +556,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg); ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg);
@ -554,15 +569,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg; ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg;
ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg; ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !sfp_1_npres; ctrl_reg_rd_data_reg[0] <= !sfp_1_npres;
ctrl_reg_rd_data_reg[2] <= sfp_1_los; ctrl_reg_rd_data_reg[2] <= sfp_1_los;
ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg; ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg;
@ -572,22 +595,25 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg; ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg;
ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg; ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg;
end end
// Flash // BPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C121; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// BPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI) ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 16; // data width ctrl_reg_rd_data_reg[23:16] <= 16; // data width
ctrl_reg_rd_data_reg[31:24] <= 24; // address width ctrl_reg_rd_data_reg[31:24] <= 24; // address width
end end
16'h0144: begin RBB+8'h40: begin
// Flash address // BPI flash ctrl: address
ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg; ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg;
ctrl_reg_rd_data_reg[23] <= flash_region_reg; ctrl_reg_rd_data_reg[23] <= flash_region_reg;
end end
16'h0148: ctrl_reg_rd_data_reg <= flash_dq_i; // Flash data RBB+8'h44: ctrl_reg_rd_data_reg <= flash_dq_i; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted) ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted)
ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted) ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted)
ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted) ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted)
@ -851,10 +877,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -958,6 +988,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -354,7 +354,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4A63093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h1ce40009" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x1ce4]
dict set params FPGA_ID "32'h4A63093" set board_device_id [expr 0x0009]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {0009} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0009},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4A63093, parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0009,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1039,11 +1042,14 @@ assign sfp_2_led[1] = 1'b0;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1ce4, 16'h0009},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4A63093, parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1ce4_0009,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -350,6 +353,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -475,13 +481,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; sfp_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -493,8 +500,9 @@ always @(posedge clk_250mhz) begin
sfp_2_sel_reg <= ctrl_reg_wr_data[17]; sfp_2_sel_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h1C: begin
// I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -502,8 +510,9 @@ always @(posedge clk_250mhz) begin
eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h2C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5]; sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5];
sfp_1_rs_reg <= ctrl_reg_wr_data[6]; sfp_1_rs_reg <= ctrl_reg_wr_data[6];
@ -513,15 +522,19 @@ always @(posedge clk_250mhz) begin
sfp_2_rs_reg <= ctrl_reg_wr_data[14]; sfp_2_rs_reg <= ctrl_reg_wr_data[14];
end end
end end
// Flash // BPI flash
16'h0144: begin RBB+8'h3C: begin
// Flash address // BPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h40: begin
// BPI flash ctrl: address
flash_addr_reg <= ctrl_reg_wr_data[22:0]; flash_addr_reg <= ctrl_reg_wr_data[22:0];
flash_region_reg <= ctrl_reg_wr_data[23]; flash_region_reg <= ctrl_reg_wr_data[23];
end end
16'h0148: flash_dq_o_reg <= ctrl_reg_wr_data; // Flash data RBB+8'h44: flash_dq_o_reg <= ctrl_reg_wr_data; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
flash_ce_n_reg <= ctrl_reg_wr_data[0]; flash_ce_n_reg <= ctrl_reg_wr_data[0];
flash_oe_n_reg <= ctrl_reg_wr_data[1]; flash_oe_n_reg <= ctrl_reg_wr_data[1];
@ -543,10 +556,12 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg); ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg);
@ -554,15 +569,23 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg; ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg;
ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg; ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg;
end end
16'h0114: begin // I2C 1
// GPIO I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header
RBB+8'h1C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // XCVR GPIO: Next header
RBB+8'h2C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !sfp_1_npres; ctrl_reg_rd_data_reg[0] <= !sfp_1_npres;
ctrl_reg_rd_data_reg[2] <= sfp_1_los; ctrl_reg_rd_data_reg[2] <= sfp_1_los;
ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg; ctrl_reg_rd_data_reg[5] <= sfp_1_tx_disable_reg;
@ -572,22 +595,25 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg; ctrl_reg_rd_data_reg[13] <= sfp_2_tx_disable_reg;
ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg; ctrl_reg_rd_data_reg[14] <= sfp_2_rs_reg;
end end
// Flash // BPI flash
16'h0140: begin RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C121; // SPI flash ctrl: Type
// Flash ID RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h38: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h3C: begin
// BPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI) ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 16; // data width ctrl_reg_rd_data_reg[23:16] <= 16; // data width
ctrl_reg_rd_data_reg[31:24] <= 24; // address width ctrl_reg_rd_data_reg[31:24] <= 24; // address width
end end
16'h0144: begin RBB+8'h40: begin
// Flash address // BPI flash ctrl: address
ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg; ctrl_reg_rd_data_reg[22:0] <= flash_addr_reg;
ctrl_reg_rd_data_reg[23] <= flash_region_reg; ctrl_reg_rd_data_reg[23] <= flash_region_reg;
end end
16'h0148: ctrl_reg_rd_data_reg <= flash_dq_i; // Flash data RBB+8'h44: ctrl_reg_rd_data_reg <= flash_dq_i; // BPI flash ctrl: data
16'h014C: begin RBB+8'h48: begin
// Flash control // BPI flash ctrl: control
ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted) ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted)
ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted) ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted)
ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted) ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted)
@ -851,10 +877,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -958,6 +988,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -354,7 +354,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x3691093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee7028" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h3691093" set board_device_id [expr 0x7028]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -147,12 +190,12 @@ dict set params STAT_ID_WIDTH "10"
set pcie [get_ips pcie3_7x_0] set pcie [get_ips pcie3_7x_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {7028} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h7028},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3691093, parameter FPGA_ID = 32'h3691093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_7028,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1283,11 +1286,14 @@ assign led = led_int;
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h7028},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3691093, parameter FPGA_ID = 32'h3691093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_7028,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -346,6 +349,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 4) begin if (PORT_COUNT > 4) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -422,9 +428,9 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -432,8 +438,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5]; sfp_1_tx_disable_reg <= ctrl_reg_wr_data[5];
sfp_1_rs_reg <= ctrl_reg_wr_data[7:6]; sfp_1_rs_reg <= ctrl_reg_wr_data[7:6];
@ -459,17 +466,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= 0; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= sfp_1_mod_detect; ctrl_reg_rd_data_reg[0] <= sfp_1_mod_detect;
ctrl_reg_rd_data_reg[1] <= sfp_1_tx_fault; ctrl_reg_rd_data_reg[1] <= sfp_1_tx_fault;
ctrl_reg_rd_data_reg[2] <= sfp_1_los; ctrl_reg_rd_data_reg[2] <= sfp_1_los;
@ -724,10 +737,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -831,6 +848,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -360,7 +360,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -170,7 +170,7 @@ create_project.tcl: Makefile $(QSF_FILES_REL) | $(IP_FILES_INT) $(IP_TCL_FILES_I
for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE "$$x" >> $@; done for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE "$$x" >> $@; done
for x in $(QSF_FILES_REL); do echo source "$$x" >> $@; done for x in $(QSF_FILES_REL); do echo source "$$x" >> $@; done
update_config.tcl: $(CONFIG_TCL_FILES_REL) update_config.tcl: $(CONFIG_TCL_FILES_REL) $(SYN_FILES_REL)
echo "project_open $(FPGA_TOP)" > $@ echo "project_open $(FPGA_TOP)" > $@
for x in $(CONFIG_TCL_FILES_REL); do echo source "$$x" >> $@; done for x in $(CONFIG_TCL_FILES_REL); do echo source "$$x" >> $@; done

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x632AC0DD]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h11720001" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x1172]
dict set params FPGA_ID "32'h632ac0dd" set board_device_id [expr 0x0001]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -167,12 +210,12 @@ set fp [open "update_ip_${pcie_ip}.tcl" "w"]
puts $fp "package require qsys" puts $fp "package require qsys"
puts $fp "load_system ip/${pcie_ip}.ip" puts $fp "load_system ip/${pcie_ip}.ip"
puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_device_id_hwtcl} {4097}" puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_device_id_hwtcl} {$pcie_device_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_vendor_id_hwtcl} {4660}" puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_vendor_id_hwtcl} {$pcie_vendor_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_class_code_hwtcl} {131072}" puts $fp "set_instance_parameter_value ${pcie} {pf0_class_code_hwtcl} {$pcie_class_code}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_revision_id_hwtcl} {0}" puts $fp "set_instance_parameter_value ${pcie} {pf0_revision_id_hwtcl} {$pcie_revision_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_dev_id_hwtcl} {1}" puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_dev_id_hwtcl} {$pcie_subsystem_device_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_vendor_id_hwtcl} {4466}" puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_vendor_id_hwtcl} {$pcie_subsystem_vendor_id}"
# configure BAR settings # configure BAR settings
proc configure_bar {fp pcie pf bar aperture} { proc configure_bar {fp pcie pf bar aperture} {

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x432AC0DD]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h11720001" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x1172]
dict set params FPGA_ID "32'h432AC0DD" set board_device_id [expr 0x0001]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -167,12 +210,12 @@ set fp [open "update_ip_${pcie_ip}.tcl" "w"]
puts $fp "package require qsys" puts $fp "package require qsys"
puts $fp "load_system ip/${pcie_ip}.ip" puts $fp "load_system ip/${pcie_ip}.ip"
puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_device_id_hwtcl} {4097}" puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_device_id_hwtcl} {$pcie_device_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_vendor_id_hwtcl} {4660}" puts $fp "set_instance_parameter_value ${pcie} {pf0_pci_type0_vendor_id_hwtcl} {$pcie_vendor_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_class_code_hwtcl} {131072}" puts $fp "set_instance_parameter_value ${pcie} {pf0_class_code_hwtcl} {$pcie_class_code}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_revision_id_hwtcl} {0}" puts $fp "set_instance_parameter_value ${pcie} {pf0_revision_id_hwtcl} {$pcie_revision_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_dev_id_hwtcl} {1}" puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_dev_id_hwtcl} {$pcie_subsystem_device_id}"
puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_vendor_id_hwtcl} {4466}" puts $fp "set_instance_parameter_value ${pcie} {pf0_subsys_vendor_id_hwtcl} {$pcie_subsystem_vendor_id}"
# configure BAR settings # configure BAR settings
proc configure_bar {fp pcie pf bar aperture} { proc configure_bar {fp pcie pf bar aperture} {

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1172, 16'h0001},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h432AC0DD, parameter FPGA_ID = 32'h432AC0DD,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1172_0001,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd1563227611,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -821,11 +824,14 @@ eth_xcvr_phy_quad_wrapper qsfp1_eth_xcvr_phy_quad (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h1c2c, 16'ha00e},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h432AC0DD, parameter FPGA_ID = 32'h432AC0DD,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h1172_0001,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd1563227611,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -327,6 +330,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -490,7 +496,7 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // 16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID
// GPIO // GPIO
// 16'h0110: begin // 16'h0110: begin
// // GPIO I2C 0 // // GPIO I2C 0
@ -886,10 +892,14 @@ endgenerate
mqnic_core_pcie_s10 #( mqnic_core_pcie_s10 #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -990,6 +1000,7 @@ mqnic_core_pcie_s10 #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -357,7 +357,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x3842093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee806c" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h3842093" set board_device_id [expr 0x806c]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -147,12 +190,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie3_ultrascale_0] set pcie [get_ips pcie3_ultrascale_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {806c} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h806c},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3842093, parameter FPGA_ID = 32'h3842093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_806c,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -1151,11 +1154,14 @@ assign led[7:4] = led_int[7:4];
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h806c},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h3842093, parameter FPGA_ID = 32'h3842093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_806c,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 1, parameter IF_COUNT = 1,
@ -360,6 +363,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 4) begin if (PORT_COUNT > 4) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -468,13 +474,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -482,22 +489,27 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp_reset_reg <= ctrl_reg_wr_data[4]; qsfp_reset_reg <= ctrl_reg_wr_data[4];
qsfp_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp_lpmode_reg <= ctrl_reg_wr_data[5];
end end
end end
// Flash // BPI flash
16'h0144: begin RBB+8'h2C: begin
// Flash address // BPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// BPI flash ctrl: address
flash_addr_reg <= ctrl_reg_wr_data[23:0]; flash_addr_reg <= ctrl_reg_wr_data[23:0];
flash_region_reg <= ctrl_reg_wr_data[25:24]; flash_region_reg <= ctrl_reg_wr_data[25:24];
end end
16'h0148: flash_dq_o_reg <= ctrl_reg_wr_data; // Flash data RBB+8'h34: flash_dq_o_reg <= ctrl_reg_wr_data; // BPI flash ctrl: data
16'h014C: begin RBB+8'h38: begin
// Flash control // BPI flash ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
flash_ce_n_reg <= ctrl_reg_wr_data[0]; flash_ce_n_reg <= ctrl_reg_wr_data[0];
flash_oe_n_reg <= ctrl_reg_wr_data[1]; flash_oe_n_reg <= ctrl_reg_wr_data[1];
@ -519,39 +531,47 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp_intl; ctrl_reg_rd_data_reg[1] <= !qsfp_intl;
ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp_reset_reg;
ctrl_reg_rd_data_reg[5] <= qsfp_lpmode_reg; ctrl_reg_rd_data_reg[5] <= qsfp_lpmode_reg;
end end
// Flash // BPI flash
16'h0140: ctrl_reg_rd_data_reg <= {8'd26, 8'd16, 8'd4, 8'd1}; // Flash ID RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C121; // SPI flash ctrl: Type
16'h0140: begin RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
// Flash ID RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// BPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI) ctrl_reg_rd_data_reg[7:0] <= 1; // type (BPI)
ctrl_reg_rd_data_reg[15:8] <= 4; // configuration (four segments) ctrl_reg_rd_data_reg[15:8] <= 4; // configuration (four segments)
ctrl_reg_rd_data_reg[23:16] <= 16; // data width ctrl_reg_rd_data_reg[23:16] <= 16; // data width
ctrl_reg_rd_data_reg[31:24] <= 26; // address width ctrl_reg_rd_data_reg[31:24] <= 26; // address width
end end
16'h0144: begin RBB+8'h30: begin
// Flash address // BPI flash ctrl: address
ctrl_reg_rd_data_reg[23:0] <= flash_addr_reg; ctrl_reg_rd_data_reg[23:0] <= flash_addr_reg;
ctrl_reg_rd_data_reg[25:24] <= flash_region_reg; ctrl_reg_rd_data_reg[25:24] <= flash_region_reg;
end end
16'h0148: ctrl_reg_rd_data_reg <= flash_dq_i; // Flash data RBB+8'h34: ctrl_reg_rd_data_reg <= flash_dq_i; // BPI flash ctrl: data
16'h014C: begin RBB+8'h38: begin
// Flash control // BPI flash ctrl: control
ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted) ctrl_reg_rd_data_reg[0] <= flash_ce_n_reg; // chip enable (inverted)
ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted) ctrl_reg_rd_data_reg[1] <= flash_oe_n_reg; // output enable (inverted)
ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted) ctrl_reg_rd_data_reg[2] <= flash_we_n_reg; // write enable (inverted)
@ -843,10 +863,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -950,6 +974,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -376,7 +376,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B31093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9076" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B31093" set board_device_id [expr 0x9076]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9076} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9076},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B31093, parameter FPGA_ID = 32'h4B31093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9076,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1649,11 +1652,14 @@ assign led[7:2] = led_int[7:2];
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9076},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B31093, parameter FPGA_ID = 32'h4B31093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9076,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -372,6 +375,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 2) begin if (PORT_COUNT > 2) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -463,13 +469,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -477,8 +484,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp1_reset_reg <= ctrl_reg_wr_data[4]; qsfp1_reset_reg <= ctrl_reg_wr_data[4];
qsfp1_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[5];
@ -488,9 +496,13 @@ always @(posedge clk_250mhz) begin
qsfp2_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp2_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI 0 control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -502,8 +514,8 @@ always @(posedge clk_250mhz) begin
qspi_0_cs_reg <= ctrl_reg_wr_data[17]; qspi_0_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0148: begin RBB+8'h34: begin
// QSPI 1 control // SPI flash ctrl: control 1
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -523,17 +535,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp1_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp1_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp1_intl; ctrl_reg_rd_data_reg[1] <= !qsfp1_intl;
ctrl_reg_rd_data_reg[4] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp1_reset_reg;
@ -543,23 +561,26 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp2_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp2_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp2_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp2_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI) ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI 0 control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_0_cs; ctrl_reg_rd_data_reg[17] <= qspi_0_cs;
end end
16'h0148: begin RBB+8'h34: begin
// QSPI 1 control // SPI flash ctrl: control 1
ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
@ -740,10 +761,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -847,6 +872,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(0), .AXIL_CSR_PASSTHROUGH_ENABLE(0),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -380,7 +380,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B31093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee9076" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B31093" set board_device_id [expr 0x9076]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -159,12 +202,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {9076} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga # module fpga #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9076},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B31093, parameter FPGA_ID = 32'h4B31093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9076,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -1415,11 +1418,14 @@ qsfp2_phy_4_inst (
fpga_core #( fpga_core #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.FPGA_ID(FPGA_ID), .BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),

View File

@ -43,11 +43,14 @@ either expressed or implied, of The Regents of the University of California.
module fpga_core # module fpga_core #
( (
// FW and board IDs // FW and board IDs
parameter FW_ID = 32'd0,
parameter FW_VER = {16'd0, 16'd1},
parameter BOARD_ID = {16'h10ee, 16'h9076},
parameter BOARD_VER = {16'd0, 16'd1},
parameter FPGA_ID = 32'h4B31093, parameter FPGA_ID = 32'h4B31093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9076,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Structural configuration // Structural configuration
parameter IF_COUNT = 2, parameter IF_COUNT = 2,
@ -412,6 +415,9 @@ parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8);
parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT);
parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8);
localparam RB_BASE_ADDR = 16'h1000;
localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}};
initial begin initial begin
if (PORT_COUNT > 8) begin if (PORT_COUNT > 8) begin
$error("Error: Max port count exceeded (instance %m)"); $error("Error: Max port count exceeded (instance %m)");
@ -524,13 +530,14 @@ always @(posedge clk_250mhz) begin
// write operation // write operation
ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_wr_ack_reg <= 1'b0;
case ({ctrl_reg_wr_addr >> 2, 2'b00}) case ({ctrl_reg_wr_addr >> 2, 2'b00})
16'h0040: begin // FW ID
// FPGA ID 8'h0C: begin
// FW ID: FPGA JTAG ID
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end end
// GPIO // I2C 0
16'h0110: begin RBB+8'h0C: begin
// GPIO I2C 0 // I2C ctrl: control
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
i2c_scl_o_reg <= ctrl_reg_wr_data[1]; i2c_scl_o_reg <= ctrl_reg_wr_data[1];
end end
@ -538,8 +545,9 @@ always @(posedge clk_250mhz) begin
i2c_sda_o_reg <= ctrl_reg_wr_data[9]; i2c_sda_o_reg <= ctrl_reg_wr_data[9];
end end
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h1C: begin
// XCVR GPIO: control 0123
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qsfp1_reset_reg <= ctrl_reg_wr_data[4]; qsfp1_reset_reg <= ctrl_reg_wr_data[4];
qsfp1_lpmode_reg <= ctrl_reg_wr_data[5]; qsfp1_lpmode_reg <= ctrl_reg_wr_data[5];
@ -549,9 +557,13 @@ always @(posedge clk_250mhz) begin
qsfp2_lpmode_reg <= ctrl_reg_wr_data[13]; qsfp2_lpmode_reg <= ctrl_reg_wr_data[13];
end end
end end
// Flash // QSPI flash
16'h0144: begin RBB+8'h2C: begin
// QSPI 0 control // SPI flash ctrl: format
fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD;
end
RBB+8'h30: begin
// SPI flash ctrl: control 0
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_0_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -563,8 +575,8 @@ always @(posedge clk_250mhz) begin
qspi_0_cs_reg <= ctrl_reg_wr_data[17]; qspi_0_cs_reg <= ctrl_reg_wr_data[17];
end end
end end
16'h0148: begin RBB+8'h34: begin
// QSPI 1 control // SPI flash ctrl: control 1
if (ctrl_reg_wr_strb[0]) begin if (ctrl_reg_wr_strb[0]) begin
qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0]; qspi_1_dq_o_reg <= ctrl_reg_wr_data[3:0];
end end
@ -584,17 +596,23 @@ always @(posedge clk_250mhz) begin
// read operation // read operation
ctrl_reg_rd_ack_reg <= 1'b1; ctrl_reg_rd_ack_reg <= 1'b1;
case ({ctrl_reg_rd_addr >> 2, 2'b00}) case ({ctrl_reg_rd_addr >> 2, 2'b00})
16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID // I2C 0
// GPIO RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type
16'h0110: begin RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version
// GPIO I2C 0 RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header
RBB+8'h0C: begin
// I2C ctrl: control
ctrl_reg_rd_data_reg[0] <= i2c_scl_i; ctrl_reg_rd_data_reg[0] <= i2c_scl_i;
ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg; ctrl_reg_rd_data_reg[1] <= i2c_scl_o_reg;
ctrl_reg_rd_data_reg[8] <= i2c_sda_i; ctrl_reg_rd_data_reg[8] <= i2c_sda_i;
ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg; ctrl_reg_rd_data_reg[9] <= i2c_sda_o_reg;
end end
16'h0120: begin // XCVR GPIO
// GPIO XCVR 0123 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type
RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version
RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // XCVR GPIO: Next header
RBB+8'h1C: begin
// XCVR GPIO: control 0123
ctrl_reg_rd_data_reg[0] <= !qsfp1_modprsl; ctrl_reg_rd_data_reg[0] <= !qsfp1_modprsl;
ctrl_reg_rd_data_reg[1] <= !qsfp1_intl; ctrl_reg_rd_data_reg[1] <= !qsfp1_intl;
ctrl_reg_rd_data_reg[4] <= qsfp1_reset_reg; ctrl_reg_rd_data_reg[4] <= qsfp1_reset_reg;
@ -604,23 +622,26 @@ always @(posedge clk_250mhz) begin
ctrl_reg_rd_data_reg[12] <= qsfp2_reset_reg; ctrl_reg_rd_data_reg[12] <= qsfp2_reset_reg;
ctrl_reg_rd_data_reg[13] <= qsfp2_lpmode_reg; ctrl_reg_rd_data_reg[13] <= qsfp2_lpmode_reg;
end end
// Flash // QSPI flash
16'h0140: begin RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type
// Flash ID RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // SPI flash ctrl: Version
RBB+8'h28: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header
RBB+8'h2C: begin
// SPI flash ctrl: format
ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI)
ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments) ctrl_reg_rd_data_reg[15:8] <= 2; // configuration (two segments)
ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI) ctrl_reg_rd_data_reg[23:16] <= 8; // data width (dual QSPI)
ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI)
end end
16'h0144: begin RBB+8'h30: begin
// QSPI 0 control // SPI flash ctrl: control 0
ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_0_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_0_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
ctrl_reg_rd_data_reg[17] <= qspi_0_cs; ctrl_reg_rd_data_reg[17] <= qspi_0_cs;
end end
16'h0148: begin RBB+8'h34: begin
// QSPI 1 control // SPI flash ctrl: control 1
ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i; ctrl_reg_rd_data_reg[3:0] <= qspi_1_dq_i;
ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe; ctrl_reg_rd_data_reg[11:8] <= qspi_1_dq_oe;
ctrl_reg_rd_data_reg[16] <= qspi_clk; ctrl_reg_rd_data_reg[16] <= qspi_clk;
@ -987,10 +1008,14 @@ endgenerate
mqnic_core_pcie_us #( mqnic_core_pcie_us #(
// FW and board IDs // FW and board IDs
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID), .FW_ID(FW_ID),
.FW_VER(FW_VER), .FW_VER(FW_VER),
.BOARD_ID(BOARD_ID), .BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER), .BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration // Structural configuration
.IF_COUNT(IF_COUNT), .IF_COUNT(IF_COUNT),
@ -1094,6 +1119,7 @@ mqnic_core_pcie_us #(
.AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH),
.AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH),
.AXIL_CSR_PASSTHROUGH_ENABLE(1), .AXIL_CSR_PASSTHROUGH_ENABLE(1),
.RB_NEXT_PTR(RB_BASE_ADDR),
// AXI lite interface configuration (application control) // AXI lite interface configuration (application control)
.AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH),

View File

@ -442,7 +442,7 @@ async def run_test_nic(dut):
# enable queues # enable queues
tb.log.info("Enable queues") tb.log.info("Enable queues")
await tb.driver.interfaces[0].ports[0].hw_regs.write_dword(mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) await tb.driver.interfaces[0].ports[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count): for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003) await tb.driver.interfaces[0].ports[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)

View File

@ -29,12 +29,55 @@
set params [dict create] set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs # FW and board IDs
dict set params FW_ID "32'd0" set fpga_id [expr 0x4B31093]
dict set params FW_VER "32'h00000001" set fw_id [expr 0x00000000]
dict set params BOARD_ID "32'h10ee95f5" set fw_ver $tag_ver
dict set params BOARD_VER "32'h00000001" set board_vendor_id [expr 0x10ee]
dict set params FPGA_ID "32'h4B31093" set board_device_id [expr 0x95f5]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Structural configuration # Structural configuration
@ -142,12 +185,12 @@ dict set params STAT_ID_WIDTH "12"
set pcie [get_ips pcie4_uscale_plus_0] set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs # PCIe IDs
set_property CONFIG.vendor_id {1234} $pcie set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID {1001} $pcie set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE {020000} $pcie set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID {00} $pcie set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} $pcie set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID {95f5} $pcie set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings # Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]] dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]

Some files were not shown because too many files have changed in this diff Show More