cndm: Initial implementation of command interface

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-03-01 13:16:24 -08:00
parent 0ff8e5fb9e
commit e27b5c0b94
16 changed files with 1578 additions and 208 deletions

View File

@@ -0,0 +1,265 @@
// SPDX-License-Identifier: CERN-OHL-S-2.0
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* Command mailbox
*/
module cndm_micro_cmd_mbox
(
input wire logic clk,
input wire logic rst,
/*
* AXI lite interface
*/
taxi_axil_if.wr_slv s_axil_wr,
taxi_axil_if.rd_slv s_axil_rd,
/*
* Control
*/
input wire logic start,
output wire logic busy,
/*
* Command interface
*/
taxi_axis_if.src m_axis_cmd,
taxi_axis_if.snk s_axis_rsp
);
localparam ADDR_W = 7;
// extract parameters
localparam DATA_W = s_axil_wr.DATA_W;
localparam STRB_W = s_axil_wr.STRB_W;
localparam VALID_ADDR_W = ADDR_W - $clog2(STRB_W);
localparam BYTE_LANES = STRB_W;
localparam BYTE_W = DATA_W/BYTE_LANES;
// check configuration
if (BYTE_W * STRB_W != DATA_W)
$fatal(0, "Error: AXI data width not evenly divisible (instance %m)");
if (2**$clog2(BYTE_LANES) != BYTE_LANES)
$fatal(0, "Error: AXI word width must be even power of two (instance %m)");
if (s_axil_rd.DATA_W != DATA_W)
$fatal(0, "Error: AXI interface configuration mismatch (instance %m)");
if (s_axil_wr.ADDR_W < ADDR_W || s_axil_wr.ADDR_W < ADDR_W)
$fatal(0, "Error: AXI address width is insufficient (instance %m)");
logic read_eligible;
logic write_eligible;
logic axil_mem_wr_en;
logic axil_mem_rd_en;
logic [4:0] axil_mem_addr;
logic cmd_mem_wr_en;
logic cmd_mem_rd_en;
logic [4:0] cmd_mem_addr;
logic last_read_reg = 1'b0, last_read_next;
logic [3:0] rd_ptr_reg = '0, rd_ptr_next;
logic [3:0] wr_ptr_reg = '0, wr_ptr_next;
logic busy_reg = 1'b0, busy_next;
logic s_axil_awready_reg = 1'b0, s_axil_awready_next;
logic s_axil_wready_reg = 1'b0, s_axil_wready_next;
logic s_axil_bvalid_reg = 1'b0, s_axil_bvalid_next;
logic s_axil_arready_reg = 1'b0, s_axil_arready_next;
// logic [DATA_W-1:0] s_axil_rdata_reg = '0, s_axil_rdata_next;
logic s_axil_rvalid_reg = 1'b0, s_axil_rvalid_next;
// logic [31:0] m_axis_cmd_tdata_reg = '0;
logic m_axis_cmd_tvalid_reg = 1'b0, m_axis_cmd_tvalid_next;
logic m_axis_cmd_tlast_reg = 1'b0, m_axis_cmd_tlast_next;
logic s_axis_rsp_tready_reg = 1'b0, s_axis_rsp_tready_next;
wire [VALID_ADDR_W-1:0] s_axil_awaddr_valid = VALID_ADDR_W'(s_axil_wr.awaddr >> (ADDR_W - VALID_ADDR_W));
wire [VALID_ADDR_W-1:0] s_axil_araddr_valid = VALID_ADDR_W'(s_axil_rd.araddr >> (ADDR_W - VALID_ADDR_W));
assign s_axil_wr.awready = s_axil_awready_reg;
assign s_axil_wr.wready = s_axil_wready_reg;
assign s_axil_wr.bresp = 2'b00;
assign s_axil_wr.buser = '0;
assign s_axil_wr.bvalid = s_axil_bvalid_reg;
assign s_axil_rd.arready = s_axil_arready_reg;
// assign s_axil_rd.rdata = s_axil_rdata_reg;
assign s_axil_rd.rresp = 2'b00;
assign s_axil_rd.ruser = '0;
assign s_axil_rd.rvalid = s_axil_rvalid_reg;
// assign m_axis_cmd.tdata = m_axis_cmd_tdata_reg;
assign m_axis_cmd.tkeep = '1;
assign m_axis_cmd.tstrb = m_axis_cmd.tkeep;
assign m_axis_cmd.tvalid = m_axis_cmd_tvalid_reg;
assign m_axis_cmd.tlast = m_axis_cmd_tlast_reg;
assign m_axis_cmd.tid = '0;
assign m_axis_cmd.tdest = '0;
assign m_axis_cmd.tuser = '0;
assign s_axis_rsp.tready = s_axis_rsp_tready_reg;
assign busy = busy_reg;
taxi_ram_2rw_1c #(
.ADDR_W(5),
.DATA_W(32),
.STRB_EN(1'b1),
.STRB_W(4)
)
ram_inst (
.clk(clk),
.a_en(axil_mem_wr_en || axil_mem_rd_en),
.a_addr(axil_mem_addr),
.a_wr_en(axil_mem_wr_en),
.a_wr_data(s_axil_wr.wdata),
.a_wr_strb(s_axil_wr.wstrb),
.a_rd_data(s_axil_rd.rdata),
.b_en(cmd_mem_wr_en || cmd_mem_rd_en),
.b_addr(cmd_mem_addr),
.b_wr_en(cmd_mem_wr_en),
.b_wr_data(s_axis_rsp.tdata),
.b_wr_strb('1),
.b_rd_data(m_axis_cmd.tdata)
);
// Register interface
always_comb begin
axil_mem_wr_en = 1'b0;
axil_mem_rd_en = 1'b0;
axil_mem_addr = s_axil_araddr_valid;
last_read_next = last_read_reg;
s_axil_awready_next = 1'b0;
s_axil_wready_next = 1'b0;
s_axil_bvalid_next = s_axil_bvalid_reg && !s_axil_wr.bready;
s_axil_arready_next = 1'b0;
s_axil_rvalid_next = s_axil_rvalid_reg && !s_axil_rd.rready;
write_eligible = s_axil_wr.awvalid && s_axil_wr.wvalid && (!s_axil_wr.bvalid || s_axil_wr.bready) && (!s_axil_wr.awready && !s_axil_wr.wready);
read_eligible = s_axil_rd.arvalid && (!s_axil_rd.rvalid || s_axil_rd.rready) && (!s_axil_rd.arready);
if (write_eligible && (!read_eligible || last_read_reg)) begin
last_read_next = 1'b0;
s_axil_awready_next = 1'b1;
s_axil_wready_next = 1'b1;
s_axil_bvalid_next = 1'b1;
axil_mem_wr_en = 1'b1;
axil_mem_addr = s_axil_awaddr_valid;
end else if (read_eligible) begin
last_read_next = 1'b1;
s_axil_arready_next = 1'b1;
s_axil_rvalid_next = 1'b1;
axil_mem_rd_en = 1'b1;
axil_mem_addr = s_axil_araddr_valid;
end
end
always_ff @(posedge clk) begin
last_read_reg <= last_read_next;
s_axil_awready_reg <= s_axil_awready_next;
s_axil_wready_reg <= s_axil_wready_next;
s_axil_bvalid_reg <= s_axil_bvalid_next;
s_axil_arready_reg <= s_axil_arready_next;
s_axil_rvalid_reg <= s_axil_rvalid_next;
if (rst) begin
last_read_reg <= 1'b0;
s_axil_awready_reg <= 1'b0;
s_axil_wready_reg <= 1'b0;
s_axil_bvalid_reg <= 1'b0;
s_axil_arready_reg <= 1'b0;
s_axil_rvalid_reg <= 1'b0;
end
end
// Command interface
always_comb begin
cmd_mem_rd_en = 1'b0;
cmd_mem_wr_en = 1'b0;
cmd_mem_addr = {1'b0, rd_ptr_reg};
rd_ptr_next = rd_ptr_reg;
wr_ptr_next = wr_ptr_reg;
busy_next = busy_reg;
m_axis_cmd_tvalid_next = m_axis_cmd_tvalid_reg && !m_axis_cmd.tready;
m_axis_cmd_tlast_next = m_axis_cmd_tlast_reg;
s_axis_rsp_tready_next = 1'b0;
if ((!m_axis_cmd_tvalid_reg || m_axis_cmd.tready) && (rd_ptr_reg != 0 || start)) begin
cmd_mem_rd_en = 1'b1;
cmd_mem_addr = {1'b0, rd_ptr_reg};
m_axis_cmd_tvalid_next = 1'b1;
m_axis_cmd_tlast_next = &rd_ptr_reg;
rd_ptr_next = rd_ptr_reg + 1;
busy_next = 1'b1;
end else if (s_axis_rsp.tvalid && !s_axis_rsp_tready_reg) begin
cmd_mem_wr_en = 1'b1;
cmd_mem_addr = {1'b1, wr_ptr_reg};
s_axis_rsp_tready_next = 1'b1;
if (s_axis_rsp.tlast) begin
wr_ptr_next = '0;
busy_next = 1'b0;
end else begin
wr_ptr_next = wr_ptr_reg + 1;
end
end
end
always_ff @(posedge clk) begin
rd_ptr_reg <= rd_ptr_next;
wr_ptr_reg <= wr_ptr_next;
busy_reg <= busy_next;
m_axis_cmd_tvalid_reg <= m_axis_cmd_tvalid_next;
m_axis_cmd_tlast_reg <= m_axis_cmd_tlast_next;
s_axis_rsp_tready_reg <= s_axis_rsp_tready_next;
if (rst) begin
rd_ptr_reg <= '0;
wr_ptr_reg <= '0;
busy_reg <= 1'b0;
m_axis_cmd_tvalid_reg <= 1'b0;
s_axis_rsp_tready_reg <= 1'b0;
end
end
endmodule
`resetall

View File

@@ -1,13 +1,18 @@
cndm_micro_core.sv
cndm_micro_cmd_mbox.sv
cndm_micro_dp_mgr.sv
cndm_micro_port.sv
cndm_micro_rx.sv
cndm_micro_tx.sv
cndm_micro_desc_rd.sv
cndm_micro_cpl_wr.sv
../lib/taxi/src/prim/rtl/taxi_ram_2rw_1c.sv
../lib/taxi/src/dma/rtl/taxi_dma_client_axis_source.sv
../lib/taxi/src/dma/rtl/taxi_dma_client_axis_sink.sv
../lib/taxi/src/dma/rtl/taxi_dma_if_mux.f
../lib/taxi/src/dma/rtl/taxi_dma_psdpram.sv
../lib/taxi/src/apb/rtl/taxi_apb_if.sv
../lib/taxi/src/apb/rtl/taxi_apb_interconnect.sv
../lib/taxi/src/axi/rtl/taxi_axil_interconnect_1s.f
../lib/taxi/src/axis/rtl/taxi_axis_async_fifo.f
../lib/taxi/src/axis/rtl/taxi_axis_arb_mux.f

View File

@@ -49,8 +49,8 @@ module cndm_micro_core #(
/*
* Control register interface
*/
taxi_axil_if.wr_slv s_axil_wr,
taxi_axil_if.rd_slv s_axil_rd,
taxi_axil_if.wr_slv s_axil_ctrl_wr,
taxi_axil_if.rd_slv s_axil_ctrl_rd,
/*
* DMA
@@ -97,8 +97,8 @@ module cndm_micro_core #(
localparam CL_PORTS = $clog2(PORTS);
localparam AXIL_ADDR_W = s_axil_wr.ADDR_W;
localparam AXIL_DATA_W = s_axil_wr.DATA_W;
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
localparam RAM_SEGS = dma_ram_wr.SEGS;
localparam RAM_SEG_ADDR_W = dma_ram_wr.SEG_ADDR_W;
@@ -106,32 +106,33 @@ localparam RAM_SEG_DATA_W = dma_ram_wr.SEG_DATA_W;
localparam RAM_SEG_BE_W = dma_ram_wr.SEG_BE_W;
localparam RAM_SEL_W = dma_ram_wr.SEL_W;
localparam PORT_OFFSET = PTP_TS_EN ? 2 : 1;
localparam PORT_OFFSET = PTP_TS_EN ? 3 : 2;
localparam PORT_BASE_ADDR = PTP_TS_EN ? 32'h00030000 : 32'h00020000;
taxi_axil_if #(
.DATA_W(s_axil_wr.DATA_W),
.DATA_W(s_axil_ctrl_wr.DATA_W),
.ADDR_W(16),
.STRB_W(s_axil_wr.STRB_W),
.AWUSER_EN(s_axil_wr.AWUSER_EN),
.AWUSER_W(s_axil_wr.AWUSER_W),
.WUSER_EN(s_axil_wr.WUSER_EN),
.WUSER_W(s_axil_wr.WUSER_W),
.BUSER_EN(s_axil_wr.BUSER_EN),
.BUSER_W(s_axil_wr.BUSER_W),
.ARUSER_EN(s_axil_wr.ARUSER_EN),
.ARUSER_W(s_axil_wr.ARUSER_W),
.RUSER_EN(s_axil_wr.RUSER_EN),
.RUSER_W(s_axil_wr.RUSER_W)
.STRB_W(s_axil_ctrl_wr.STRB_W),
.AWUSER_EN(s_axil_ctrl_wr.AWUSER_EN),
.AWUSER_W(s_axil_ctrl_wr.AWUSER_W),
.WUSER_EN(s_axil_ctrl_wr.WUSER_EN),
.WUSER_W(s_axil_ctrl_wr.WUSER_W),
.BUSER_EN(s_axil_ctrl_wr.BUSER_EN),
.BUSER_W(s_axil_ctrl_wr.BUSER_W),
.ARUSER_EN(s_axil_ctrl_wr.ARUSER_EN),
.ARUSER_W(s_axil_ctrl_wr.ARUSER_W),
.RUSER_EN(s_axil_ctrl_wr.RUSER_EN),
.RUSER_W(s_axil_ctrl_wr.RUSER_W)
)
s_axil_ctrl[PORTS+PORT_OFFSET]();
axil_ctrl[PORTS+PORT_OFFSET]();
taxi_axil_interconnect_1s #(
.M_COUNT($size(s_axil_ctrl)),
.ADDR_W(s_axil_wr.ADDR_W),
.M_COUNT($size(axil_ctrl)),
.ADDR_W(s_axil_ctrl_wr.ADDR_W),
.M_REGIONS(1),
.M_BASE_ADDR('0),
.M_ADDR_W({$size(s_axil_ctrl){{1{32'd16}}}}),
.M_SECURE({$size(s_axil_ctrl){1'b0}})
.M_ADDR_W({$size(axil_ctrl){{1{32'd16}}}}),
.M_SECURE({$size(axil_ctrl){1'b0}})
)
port_intercon_inst (
.clk(clk),
@@ -140,14 +141,14 @@ port_intercon_inst (
/*
* AXI4-lite slave interface
*/
.s_axil_wr(s_axil_wr),
.s_axil_rd(s_axil_rd),
.s_axil_wr(s_axil_ctrl_wr),
.s_axil_rd(s_axil_ctrl_rd),
/*
* AXI4-lite master interfaces
*/
.m_axil_wr(s_axil_ctrl),
.m_axil_rd(s_axil_ctrl)
.m_axil_wr(axil_ctrl),
.m_axil_rd(axil_ctrl)
);
logic s_axil_awready_reg = 1'b0;
@@ -158,53 +159,64 @@ logic s_axil_arready_reg = 1'b0;
logic [AXIL_DATA_W-1:0] s_axil_rdata_reg = '0;
logic s_axil_rvalid_reg = 1'b0;
assign s_axil_ctrl[0].awready = s_axil_awready_reg;
assign s_axil_ctrl[0].wready = s_axil_wready_reg;
assign s_axil_ctrl[0].bresp = '0;
assign s_axil_ctrl[0].buser = '0;
assign s_axil_ctrl[0].bvalid = s_axil_bvalid_reg;
assign axil_ctrl[0].awready = s_axil_awready_reg;
assign axil_ctrl[0].wready = s_axil_wready_reg;
assign axil_ctrl[0].bresp = '0;
assign axil_ctrl[0].buser = '0;
assign axil_ctrl[0].bvalid = s_axil_bvalid_reg;
assign s_axil_ctrl[0].arready = s_axil_arready_reg;
assign s_axil_ctrl[0].rdata = s_axil_rdata_reg;
assign s_axil_ctrl[0].rresp = '0;
assign s_axil_ctrl[0].ruser = '0;
assign s_axil_ctrl[0].rvalid = s_axil_rvalid_reg;
assign axil_ctrl[0].arready = s_axil_arready_reg;
assign axil_ctrl[0].rdata = s_axil_rdata_reg;
assign axil_ctrl[0].rresp = '0;
assign axil_ctrl[0].ruser = '0;
assign axil_ctrl[0].rvalid = s_axil_rvalid_reg;
logic cmd_mbox_start_reg = 1'b0;
wire cmd_mbox_busy;
always_ff @(posedge clk) begin
s_axil_awready_reg <= 1'b0;
s_axil_wready_reg <= 1'b0;
s_axil_bvalid_reg <= s_axil_bvalid_reg && !s_axil_ctrl[0].bready;
s_axil_bvalid_reg <= s_axil_bvalid_reg && !axil_ctrl[0].bready;
s_axil_arready_reg <= 1'b0;
s_axil_rvalid_reg <= s_axil_rvalid_reg && !s_axil_ctrl[0].rready;
s_axil_rvalid_reg <= s_axil_rvalid_reg && !axil_ctrl[0].rready;
if (s_axil_ctrl[0].awvalid && s_axil_ctrl[0].wvalid && !s_axil_bvalid_reg) begin
cmd_mbox_start_reg <= 1'b0;
if (axil_ctrl[0].awvalid && axil_ctrl[0].wvalid && !s_axil_bvalid_reg) begin
s_axil_awready_reg <= 1'b1;
s_axil_wready_reg <= 1'b1;
s_axil_bvalid_reg <= 1'b1;
case ({s_axil_ctrl[0].awaddr[15:2], 2'b00})
case ({axil_ctrl[0].awaddr[15:2], 2'b00})
// 16'h0100: begin
// txq_en_reg <= s_axil_ctrl[0].wdata[0];
// txq_size_reg <= s_axil_ctrl[0].wdata[19:16];
// txq_en_reg <= axil_ctrl[0].wdata[0];
// txq_size_reg <= axil_ctrl[0].wdata[19:16];
// end
// 16'h0104: txq_prod_reg <= s_axil_ctrl[0].wdata[15:0];
// 16'h0108: txq_base_addr_reg[31:0] <= s_axil_ctrl[0].wdata;
// 16'h010c: txq_base_addr_reg[63:32] <= s_axil_ctrl[0].wdata;
// 16'h0104: txq_prod_reg <= axil_ctrl[0].wdata[15:0];
// 16'h0108: txq_base_addr_reg[31:0] <= axil_ctrl[0].wdata;
// 16'h010c: txq_base_addr_reg[63:32] <= axil_ctrl[0].wdata;
16'h0200: begin
cmd_mbox_start_reg <= axil_ctrl[0].wdata[0];
end
default: begin end
endcase
end
if (s_axil_ctrl[0].arvalid && !s_axil_rvalid_reg) begin
if (axil_ctrl[0].arvalid && !s_axil_rvalid_reg) begin
s_axil_rdata_reg <= '0;
s_axil_arready_reg <= 1'b1;
s_axil_rvalid_reg <= 1'b1;
case ({s_axil_ctrl[0].araddr[15:2], 2'b00})
case ({axil_ctrl[0].araddr[15:2], 2'b00})
16'h0100: s_axil_rdata_reg <= PORTS; // port count
16'h0104: s_axil_rdata_reg <= PTP_TS_EN ? 32'h00020000 : 32'h00010000; // port offset
16'h0104: s_axil_rdata_reg <= PORT_BASE_ADDR; // port offset
16'h0108: s_axil_rdata_reg <= 32'h00010000; // port stride
16'h0200: begin
s_axil_rdata_reg[0] <= cmd_mbox_busy;
end
default: begin end
endcase
end
@@ -219,6 +231,106 @@ always_ff @(posedge clk) begin
end
end
// command mailbox
taxi_axis_if #(
.DATA_W(32),
.KEEP_EN(1),
.LAST_EN(1),
.ID_EN(0),
.DEST_EN(0),
.USER_EN(0)
) axis_cmd();
taxi_axis_if #(
.DATA_W(32),
.KEEP_EN(1),
.LAST_EN(1),
.ID_EN(0),
.DEST_EN(0),
.USER_EN(0)
) axis_rsp();
cndm_micro_cmd_mbox
cmd_mbox_inst (
.clk(clk),
.rst(rst),
/*
* AXI lite interface
*/
.s_axil_wr(axil_ctrl[1]),
.s_axil_rd(axil_ctrl[1]),
/*
* Control
*/
.start(cmd_mbox_start_reg),
.busy(cmd_mbox_busy),
/*
* Command interface
*/
.m_axis_cmd(axis_cmd),
.s_axis_rsp(axis_rsp)
);
// datapath manager
taxi_apb_if #(
.DATA_W(32),
.ADDR_W(16+CL_PORTS)
)
apb_dp_ctrl();
cndm_micro_dp_mgr #(
.PORTS(PORTS),
.PORT_BASE_ADDR(PORT_BASE_ADDR)
)
dp_mgr_inst (
.clk(clk),
.rst(rst),
/*
* Command interface
*/
.s_axis_cmd(axis_cmd),
.m_axis_rsp(axis_rsp),
/*
* APB master interface (datapath control)
*/
.m_apb_dp_ctrl(apb_dp_ctrl)
);
taxi_apb_if #(
.DATA_W(32),
.ADDR_W(16)
)
apb_port_dp_ctrl[PORTS]();
taxi_apb_interconnect #(
.M_CNT($size(apb_port_dp_ctrl)),
.ADDR_W(apb_dp_ctrl.ADDR_W),
.M_REGIONS(1),
.M_BASE_ADDR('0),
.M_ADDR_W({$size(apb_port_dp_ctrl){{1{32'd16}}}}),
.M_SECURE({$size(apb_port_dp_ctrl){1'b0}})
)
port_dp_intercon_inst (
.clk(clk),
.rst(rst),
/*
* APB slave interface
*/
.s_apb(apb_dp_ctrl),
/*
* APB master interfaces
*/
.m_apb(apb_port_dp_ctrl)
);
if (PTP_TS_EN) begin : ptp
taxi_ptp_td_phc_axil #(
@@ -232,8 +344,8 @@ if (PTP_TS_EN) begin : ptp
/*
* Control register interface
*/
.s_axil_wr(s_axil_ctrl[1]),
.s_axil_rd(s_axil_ctrl[1]),
.s_axil_wr(axil_ctrl[2]),
.s_axil_rd(axil_ctrl[2]),
/*
* PTP
@@ -362,8 +474,13 @@ for (genvar p = 0; p < PORTS; p = p + 1) begin : port
/*
* Control register interface
*/
.s_axil_wr(s_axil_ctrl[PORT_OFFSET+p]),
.s_axil_rd(s_axil_ctrl[PORT_OFFSET+p]),
.s_axil_ctrl_wr(axil_ctrl[PORT_OFFSET+p]),
.s_axil_ctrl_rd(axil_ctrl[PORT_OFFSET+p]),
/*
* Datapath control register interface
*/
.s_apb_dp_ctrl(apb_port_dp_ctrl[p]),
/*
* DMA

View File

@@ -0,0 +1,546 @@
// SPDX-License-Identifier: CERN-OHL-S-2.0
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* Datapath manager
*/
module cndm_micro_dp_mgr #
(
parameter PORTS = 2,
parameter PORT_BASE_ADDR = 0
)
(
input wire logic clk,
input wire logic rst,
/*
* Command interface
*/
taxi_axis_if.snk s_axis_cmd,
taxi_axis_if.src m_axis_rsp,
/*
* APB master interface (datapath control)
*/
taxi_apb_if.mst m_apb_dp_ctrl
);
// extract parameters
localparam DP_APB_ADDR_W = m_apb_dp_ctrl.ADDR_W;
localparam DP_APB_DATA_W = m_apb_dp_ctrl.DATA_W;
localparam DP_APB_STRB_W = m_apb_dp_ctrl.STRB_W;
typedef enum logic [15:0] {
CMD_OP_NOP = 16'h0000,
CMD_OP_CREATE_EQ = 16'h0200,
CMD_OP_MODIFY_EQ = 16'h0201,
CMD_OP_QUERY_EQ = 16'h0202,
CMD_OP_DESTROY_EQ = 16'h0203,
CMD_OP_CREATE_CQ = 16'h0210,
CMD_OP_MODIFY_CQ = 16'h0211,
CMD_OP_QUERY_CQ = 16'h0212,
CMD_OP_DESTROY_CQ = 16'h0213,
CMD_OP_CREATE_SQ = 16'h0220,
CMD_OP_MODIFY_SQ = 16'h0221,
CMD_OP_QUERY_SQ = 16'h0222,
CMD_OP_DESTROY_SQ = 16'h0223,
CMD_OP_CREATE_RQ = 16'h0230,
CMD_OP_MODIFY_RQ = 16'h0231,
CMD_OP_QUERY_RQ = 16'h0232,
CMD_OP_DESTROY_RQ = 16'h0233,
CMD_OP_CREATE_QP = 16'h0240,
CMD_OP_MODIFY_QP = 16'h0241,
CMD_OP_QUERY_QP = 16'h0242,
CMD_OP_DESTROY_QP = 16'h0243
} cmd_opcode_t;
typedef enum logic [4:0] {
STATE_IDLE,
STATE_START,
STATE_Q_RESET_1,
STATE_Q_RESET_2,
STATE_Q_SET_BASE_L,
STATE_Q_SET_BASE_H,
STATE_Q_ENABLE,
STATE_Q_DISABLE,
STATE_SEND_RSP,
STATE_PAD_RSP
} state_t;
state_t state_reg = STATE_IDLE, state_next;
logic s_axis_cmd_tready_reg = 1'b0, s_axis_cmd_tready_next;
logic [31:0] m_axis_rsp_tdata_reg = '0, m_axis_rsp_tdata_next;
logic m_axis_rsp_tvalid_reg = 1'b0, m_axis_rsp_tvalid_next;
logic m_axis_rsp_tlast_reg = 1'b0, m_axis_rsp_tlast_next;
logic [DP_APB_ADDR_W-1:0] m_apb_dp_ctrl_paddr_reg = '0, m_apb_dp_ctrl_paddr_next;
logic m_apb_dp_ctrl_psel_reg = 1'b0, m_apb_dp_ctrl_psel_next;
logic m_apb_dp_ctrl_penable_reg = 1'b0, m_apb_dp_ctrl_penable_next;
logic m_apb_dp_ctrl_pwrite_reg = 1'b0, m_apb_dp_ctrl_pwrite_next;
logic [DP_APB_DATA_W-1:0] m_apb_dp_ctrl_pwdata_reg = '0, m_apb_dp_ctrl_pwdata_next;
logic [DP_APB_STRB_W-1:0] m_apb_dp_ctrl_pstrb_reg = '0, m_apb_dp_ctrl_pstrb_next;
// command RAM
localparam CMD_AW = 4;
logic [31:0] cmd_ram[2**CMD_AW];
logic [31:0] cmd_ram_wr_data;
logic [CMD_AW-1:0] cmd_ram_wr_addr;
logic cmd_ram_wr_en;
logic [CMD_AW-1:0] cmd_ram_rd_addr;
wire [31:0] cmd_ram_rd_data = cmd_ram[cmd_ram_rd_addr];
assign s_axis_cmd.tready = s_axis_cmd_tready_reg;
assign m_axis_rsp.tdata = m_axis_rsp_tdata_reg;
assign m_axis_rsp.tkeep = '1;
assign m_axis_rsp.tstrb = m_axis_rsp.tkeep;
assign m_axis_rsp.tvalid = m_axis_rsp_tvalid_reg;
assign m_axis_rsp.tlast = m_axis_rsp_tlast_reg;
assign m_axis_rsp.tid = '0;
assign m_axis_rsp.tdest = '0;
assign m_axis_rsp.tuser = '0;
assign m_apb_dp_ctrl.paddr = m_apb_dp_ctrl_paddr_reg;
assign m_apb_dp_ctrl.pprot = 3'b010;
assign m_apb_dp_ctrl.psel = m_apb_dp_ctrl_psel_reg;
assign m_apb_dp_ctrl.penable = m_apb_dp_ctrl_penable_reg;
assign m_apb_dp_ctrl.pwrite = m_apb_dp_ctrl_pwrite_reg;
assign m_apb_dp_ctrl.pwdata = m_apb_dp_ctrl_pwdata_reg;
assign m_apb_dp_ctrl.pstrb = m_apb_dp_ctrl_pstrb_reg;
assign m_apb_dp_ctrl.pauser = '0;
assign m_apb_dp_ctrl.pwuser = '0;
logic cmd_frame_reg = 1'b0, cmd_frame_next;
logic [3:0] cmd_ptr_reg = '0, cmd_ptr_next;
logic rsp_frame_reg = 1'b0, rsp_frame_next;
logic [3:0] rsp_ptr_reg = '0, rsp_ptr_next;
logic drop_cmd_reg = 1'b0, drop_cmd_next;
logic [15:0] opcode_reg = '0, opcode_next;
logic [31:0] flags_reg = '0, flags_next;
logic [15:0] port_reg = '0, port_next;
logic [23:0] qn_reg = '0, qn_next;
logic [DP_APB_ADDR_W-1:0] block_base_addr_reg = '0, block_base_addr_next;
always_comb begin
state_next = STATE_IDLE;
s_axis_cmd_tready_next = 1'b0;
m_axis_rsp_tdata_next = m_axis_rsp_tdata_reg;
m_axis_rsp_tvalid_next = m_axis_rsp_tvalid_reg && !m_axis_rsp.tready;
m_axis_rsp_tlast_next = m_axis_rsp_tlast_reg;
m_apb_dp_ctrl_paddr_next = m_apb_dp_ctrl_paddr_reg;
m_apb_dp_ctrl_psel_next = m_apb_dp_ctrl_psel_reg && !m_apb_dp_ctrl.pready;
m_apb_dp_ctrl_penable_next = m_apb_dp_ctrl_psel_reg && !m_apb_dp_ctrl.pready;
m_apb_dp_ctrl_pwrite_next = m_apb_dp_ctrl_pwrite_reg;
m_apb_dp_ctrl_pwdata_next = m_apb_dp_ctrl_pwdata_reg;
m_apb_dp_ctrl_pstrb_next = m_apb_dp_ctrl_pstrb_reg;
cmd_ram_wr_data = s_axis_cmd.tdata;
cmd_ram_wr_addr = cmd_ptr_reg;
cmd_ram_wr_en = 1'b0;
cmd_ram_rd_addr = '0;
cmd_frame_next = cmd_frame_reg;
cmd_ptr_next = cmd_ptr_reg;
rsp_frame_next = rsp_frame_reg;
rsp_ptr_next = rsp_ptr_reg;
drop_cmd_next = drop_cmd_reg;
opcode_next = opcode_reg;
flags_next = flags_reg;
port_next = port_reg;
qn_next = qn_reg;
block_base_addr_next = block_base_addr_reg;
if (s_axis_cmd.tready && s_axis_cmd.tvalid) begin
if (s_axis_cmd.tlast) begin
cmd_frame_next = 1'b0;
cmd_ptr_next = '0;
end else begin
cmd_ptr_next = cmd_ptr_reg + 1;
cmd_frame_next = 1'b1;
end
end
case (state_reg)
STATE_IDLE: begin
s_axis_cmd_tready_next = !m_axis_rsp_tvalid_reg && !rsp_frame_reg;
cmd_ram_wr_data = s_axis_cmd.tdata;
cmd_ram_wr_addr = cmd_ptr_reg;
cmd_ram_wr_en = 1'b1;
// save some important fields
case (cmd_ptr_reg)
4'd0: opcode_next = s_axis_cmd.tdata[31:16];
4'd1: flags_next = s_axis_cmd.tdata;
4'd2: port_next = s_axis_cmd.tdata[15:0];
4'd3: qn_next = s_axis_cmd.tdata[23:0];
default: begin end
endcase
if (s_axis_cmd.tready && s_axis_cmd.tvalid && !drop_cmd_reg) begin
if (s_axis_cmd.tlast || &cmd_ptr_reg) begin
drop_cmd_next = !s_axis_cmd.tlast;
state_next = STATE_START;
end else begin
state_next = STATE_IDLE;
end
end else begin
state_next = STATE_IDLE;
end
end
STATE_START: begin
// determine block base address
case (opcode_reg)
CMD_OP_CREATE_EQ,
CMD_OP_MODIFY_EQ,
CMD_OP_QUERY_EQ,
CMD_OP_DESTROY_EQ:
begin
// EQ
block_base_addr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 16'h0000);
end
CMD_OP_CREATE_CQ,
CMD_OP_MODIFY_CQ,
CMD_OP_QUERY_CQ,
CMD_OP_DESTROY_CQ:
begin
// CQ
if (qn_reg[0]) begin
block_base_addr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 16'h0300);
end else begin
block_base_addr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 16'h0400);
end
end
CMD_OP_CREATE_SQ,
CMD_OP_MODIFY_SQ,
CMD_OP_QUERY_SQ,
CMD_OP_DESTROY_SQ:
begin
// SQ
block_base_addr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 16'h0100);
end
CMD_OP_CREATE_RQ,
CMD_OP_MODIFY_RQ,
CMD_OP_QUERY_RQ,
CMD_OP_DESTROY_RQ:
begin
// RQ
block_base_addr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 16'h0200);
end
default: begin end
endcase
case (opcode_reg)
16'h0000: begin
// NOP
m_axis_rsp_tdata_next = '0; // TODO
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
state_next = STATE_SEND_RSP;
end
CMD_OP_CREATE_EQ,
CMD_OP_CREATE_CQ,
CMD_OP_CREATE_SQ,
CMD_OP_CREATE_RQ:
begin
// create queue operation
state_next = STATE_Q_RESET_1;
end
CMD_OP_MODIFY_EQ,
CMD_OP_MODIFY_CQ,
CMD_OP_MODIFY_SQ,
CMD_OP_MODIFY_RQ:
begin
// modify queue operation
m_axis_rsp_tdata_next = '0; // TODO
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
// determine base address
state_next = STATE_PAD_RSP;
end
CMD_OP_QUERY_EQ,
CMD_OP_QUERY_CQ,
CMD_OP_QUERY_SQ,
CMD_OP_QUERY_RQ:
begin
// query queue operation
m_axis_rsp_tdata_next = '0; // TODO
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
// determine base address
state_next = STATE_PAD_RSP;
end
CMD_OP_DESTROY_EQ,
CMD_OP_DESTROY_CQ,
CMD_OP_DESTROY_SQ,
CMD_OP_DESTROY_RQ:
begin
// destroy queue operation
state_next = STATE_Q_DISABLE;
end
default: begin
// unknown opcode
m_axis_rsp_tdata_next = '0; // TODO error code
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
state_next = STATE_PAD_RSP;
end
endcase
end
STATE_Q_RESET_1: begin
// reset queue 1
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h0000;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
m_apb_dp_ctrl_pstrb_next = '1;
state_next = STATE_Q_RESET_2;
end else begin
state_next = STATE_Q_RESET_1;
end
end
STATE_Q_RESET_2: begin
// reset queue 2
cmd_ram_wr_data = 32'(block_base_addr_reg + 16'h0004) + PORT_BASE_ADDR;
cmd_ram_wr_addr = 7;
cmd_ram_wr_en = 1'b1;
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h0004;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
m_apb_dp_ctrl_pstrb_next = '1;
state_next = STATE_Q_SET_BASE_L;
end else begin
state_next = STATE_Q_RESET_2;
end
end
STATE_Q_SET_BASE_L: begin
// set queue base addr (LSB)
cmd_ram_rd_addr = 8;
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h0008;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
m_apb_dp_ctrl_pstrb_next = '1;
state_next = STATE_Q_SET_BASE_H;
end else begin
state_next = STATE_Q_SET_BASE_L;
end
end
STATE_Q_SET_BASE_H: begin
// set queue base addr (MSB)
cmd_ram_rd_addr = 9;
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h000C;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
m_apb_dp_ctrl_pstrb_next = '1;
state_next = STATE_Q_ENABLE;
end else begin
state_next = STATE_Q_SET_BASE_H;
end
end
STATE_Q_ENABLE: begin
// enable queue
cmd_ram_rd_addr = 6;
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h0000;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = '0;
m_apb_dp_ctrl_pwdata_next[19:16] = cmd_ram_rd_data[3:0];
m_apb_dp_ctrl_pwdata_next[0] = 1'b1;
m_apb_dp_ctrl_pstrb_next = '1;
m_axis_rsp_tdata_next = '0; // TODO
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
state_next = STATE_SEND_RSP;
end else begin
state_next = STATE_Q_ENABLE;
end
end
STATE_Q_DISABLE: begin
// disable queue
if (!m_apb_dp_ctrl_psel_reg) begin
m_apb_dp_ctrl_paddr_next = block_base_addr_reg + 16'h0000;
m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
m_apb_dp_ctrl_pstrb_next = '1;
m_axis_rsp_tdata_next = '0; // TODO
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = 1'b0;
state_next = STATE_SEND_RSP;
end else begin
state_next = STATE_Q_DISABLE;
end
end
STATE_SEND_RSP: begin
// send response in the form of an edited command
cmd_ram_rd_addr = rsp_ptr_reg;
if (m_axis_rsp.tready || !m_axis_rsp.tvalid) begin
m_axis_rsp_tdata_next = cmd_ram_rd_data;
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = &rsp_ptr_reg;
if (&rsp_ptr_reg) begin
state_next = STATE_IDLE;
end else begin
state_next = STATE_SEND_RSP;
end
end else begin
state_next = STATE_SEND_RSP;
end
end
STATE_PAD_RSP: begin
// zero pad response
if (m_axis_rsp.tready || !m_axis_rsp.tvalid) begin
m_axis_rsp_tdata_next = '0;
m_axis_rsp_tvalid_next = 1'b1;
m_axis_rsp_tlast_next = &rsp_ptr_reg;
if (&rsp_ptr_reg) begin
state_next = STATE_IDLE;
end else begin
state_next = STATE_PAD_RSP;
end
end else begin
state_next = STATE_PAD_RSP;
end
end
default: begin
// unknown state; return to idle
state_next = STATE_IDLE;
end
endcase
if (drop_cmd_reg) begin
s_axis_cmd_tready_next = 1'b1;
if (s_axis_cmd.tready && s_axis_cmd.tvalid) begin
drop_cmd_next = !s_axis_cmd.tlast;
end
end
if (m_axis_rsp_tvalid_next && (!m_axis_rsp_tvalid_reg || m_axis_rsp.tready)) begin
if (m_axis_rsp_tlast_next) begin
rsp_ptr_next = '0;
end else begin
rsp_ptr_next = rsp_ptr_reg + 1;
rsp_frame_next = 1'b1;
end
end
if (m_axis_rsp.tready && m_axis_rsp.tvalid) begin
if (m_axis_rsp.tlast) begin
rsp_frame_next = 1'b0;
rsp_ptr_next = '0;
end
end
end
always_ff @(posedge clk) begin
if (cmd_ram_wr_en) begin
cmd_ram[cmd_ram_wr_addr] = cmd_ram_wr_data;
end
end
always_ff @(posedge clk) begin
state_reg <= state_next;
s_axis_cmd_tready_reg <= s_axis_cmd_tready_next;
m_axis_rsp_tdata_reg <= m_axis_rsp_tdata_next;
m_axis_rsp_tvalid_reg <= m_axis_rsp_tvalid_next;
m_axis_rsp_tlast_reg <= m_axis_rsp_tlast_next;
m_apb_dp_ctrl_paddr_reg <= m_apb_dp_ctrl_paddr_next;
m_apb_dp_ctrl_psel_reg <= m_apb_dp_ctrl_psel_next;
m_apb_dp_ctrl_penable_reg <= m_apb_dp_ctrl_penable_next;
m_apb_dp_ctrl_pwrite_reg <= m_apb_dp_ctrl_pwrite_next;
m_apb_dp_ctrl_pwdata_reg <= m_apb_dp_ctrl_pwdata_next;
m_apb_dp_ctrl_pstrb_reg <= m_apb_dp_ctrl_pstrb_next;
cmd_frame_reg <= cmd_frame_next;
cmd_ptr_reg <= cmd_ptr_next;
rsp_frame_reg <= rsp_frame_next;
rsp_ptr_reg <= rsp_ptr_next;
drop_cmd_reg <= drop_cmd_next;
opcode_reg <= opcode_next;
flags_reg <= flags_next;
port_reg <= port_next;
qn_reg <= qn_next;
block_base_addr_reg <= block_base_addr_next;
if (rst) begin
state_reg <= STATE_IDLE;
s_axis_cmd_tready_reg <= 1'b0;
m_axis_rsp_tvalid_reg <= 1'b0;
m_apb_dp_ctrl_psel_reg <= 1'b0;
m_apb_dp_ctrl_penable_reg <= 1'b0;
cmd_frame_reg <= 1'b0;
cmd_ptr_reg <= '0;
rsp_frame_reg <= 1'b0;
rsp_ptr_reg <= '0;
drop_cmd_reg <= 1'b0;
end
end
endmodule
`resetall

View File

@@ -523,8 +523,8 @@ core_inst (
/*
* Control register interface
*/
.s_axil_wr(axil_ctrl_bar),
.s_axil_rd(axil_ctrl_bar),
.s_axil_ctrl_wr(axil_ctrl_bar),
.s_axil_ctrl_rd(axil_ctrl_bar),
/*
* DMA

View File

@@ -26,8 +26,13 @@ module cndm_micro_port #(
/*
* Control register interface
*/
taxi_axil_if.wr_slv s_axil_wr,
taxi_axil_if.rd_slv s_axil_rd,
taxi_axil_if.wr_slv s_axil_ctrl_wr,
taxi_axil_if.rd_slv s_axil_ctrl_rd,
/*
* Datapath control register interface
*/
taxi_apb_if.slv s_apb_dp_ctrl,
/*
* DMA
@@ -61,8 +66,8 @@ module cndm_micro_port #(
taxi_axis_if.snk mac_axis_rx
);
localparam AXIL_ADDR_W = s_axil_wr.ADDR_W;
localparam AXIL_DATA_W = s_axil_wr.DATA_W;
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
localparam RAM_SEGS = dma_ram_wr.SEGS;
localparam RAM_SEG_ADDR_W = dma_ram_wr.SEG_ADDR_W;
@@ -90,128 +95,222 @@ logic [3:0] rxcq_size_reg = '0;
logic [63:0] rxcq_base_addr_reg = '0;
wire [15:0] rxcq_prod;
logic s_axil_awready_reg = 1'b0;
logic s_axil_wready_reg = 1'b0;
logic s_axil_bvalid_reg = 1'b0;
logic s_axil_ctrl_awready_reg = 1'b0;
logic s_axil_ctrl_wready_reg = 1'b0;
logic s_axil_ctrl_bvalid_reg = 1'b0;
logic s_axil_arready_reg = 1'b0;
logic [AXIL_DATA_W-1:0] s_axil_rdata_reg = '0;
logic s_axil_rvalid_reg = 1'b0;
logic s_axil_ctrl_arready_reg = 1'b0;
logic [AXIL_DATA_W-1:0] s_axil_ctrl_rdata_reg = '0;
logic s_axil_ctrl_rvalid_reg = 1'b0;
assign s_axil_wr.awready = s_axil_awready_reg;
assign s_axil_wr.wready = s_axil_wready_reg;
assign s_axil_wr.bresp = '0;
assign s_axil_wr.buser = '0;
assign s_axil_wr.bvalid = s_axil_bvalid_reg;
assign s_axil_ctrl_wr.awready = s_axil_ctrl_awready_reg;
assign s_axil_ctrl_wr.wready = s_axil_ctrl_wready_reg;
assign s_axil_ctrl_wr.bresp = '0;
assign s_axil_ctrl_wr.buser = '0;
assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg;
assign s_axil_rd.arready = s_axil_arready_reg;
assign s_axil_rd.rdata = s_axil_rdata_reg;
assign s_axil_rd.rresp = '0;
assign s_axil_rd.ruser = '0;
assign s_axil_rd.rvalid = s_axil_rvalid_reg;
assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg;
assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg;
assign s_axil_ctrl_rd.rresp = '0;
assign s_axil_ctrl_rd.ruser = '0;
assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg;
logic s_apb_dp_ctrl_pready_reg = 1'b0;
logic [AXIL_DATA_W-1:0] s_apb_dp_ctrl_prdata_reg = '0;
assign s_apb_dp_ctrl.pready = s_apb_dp_ctrl_pready_reg;
assign s_apb_dp_ctrl.prdata = s_apb_dp_ctrl_prdata_reg;
assign s_apb_dp_ctrl.pslverr = 1'b0;
assign s_apb_dp_ctrl.pruser = '0;
assign s_apb_dp_ctrl.pbuser = '0;
always_ff @(posedge clk) begin
s_axil_awready_reg <= 1'b0;
s_axil_wready_reg <= 1'b0;
s_axil_bvalid_reg <= s_axil_bvalid_reg && !s_axil_wr.bready;
s_axil_ctrl_awready_reg <= 1'b0;
s_axil_ctrl_wready_reg <= 1'b0;
s_axil_ctrl_bvalid_reg <= s_axil_ctrl_bvalid_reg && !s_axil_ctrl_wr.bready;
s_axil_arready_reg <= 1'b0;
s_axil_rvalid_reg <= s_axil_rvalid_reg && !s_axil_rd.rready;
s_axil_ctrl_arready_reg <= 1'b0;
s_axil_ctrl_rvalid_reg <= s_axil_ctrl_rvalid_reg && !s_axil_ctrl_rd.rready;
if (s_axil_wr.awvalid && s_axil_wr.wvalid && !s_axil_bvalid_reg) begin
s_axil_awready_reg <= 1'b1;
s_axil_wready_reg <= 1'b1;
s_axil_bvalid_reg <= 1'b1;
s_apb_dp_ctrl_pready_reg <= 1'b0;
case ({s_axil_wr.awaddr[15:2], 2'b00})
if (s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin
s_axil_ctrl_awready_reg <= 1'b1;
s_axil_ctrl_wready_reg <= 1'b1;
s_axil_ctrl_bvalid_reg <= 1'b1;
case ({s_axil_ctrl_wr.awaddr[15:2], 2'b00})
16'h0100: begin
txq_en_reg <= s_axil_wr.wdata[0];
txq_size_reg <= s_axil_wr.wdata[19:16];
txq_en_reg <= s_axil_ctrl_wr.wdata[0];
txq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
end
16'h0104: txq_prod_reg <= s_axil_wr.wdata[15:0];
16'h0108: txq_base_addr_reg[31:0] <= s_axil_wr.wdata;
16'h010c: txq_base_addr_reg[63:32] <= s_axil_wr.wdata;
16'h0104: txq_prod_reg <= s_axil_ctrl_wr.wdata[15:0];
16'h0108: txq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
16'h010c: txq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
16'h0200: begin
rxq_en_reg <= s_axil_wr.wdata[0];
rxq_size_reg <= s_axil_wr.wdata[19:16];
rxq_en_reg <= s_axil_ctrl_wr.wdata[0];
rxq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
end
16'h0204: rxq_prod_reg <= s_axil_wr.wdata[15:0];
16'h0208: rxq_base_addr_reg[31:0] <= s_axil_wr.wdata;
16'h020c: rxq_base_addr_reg[63:32] <= s_axil_wr.wdata;
16'h0204: rxq_prod_reg <= s_axil_ctrl_wr.wdata[15:0];
16'h0208: rxq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
16'h020c: rxq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
16'h0300: begin
txcq_en_reg <= s_axil_wr.wdata[0];
txcq_size_reg <= s_axil_wr.wdata[19:16];
txcq_en_reg <= s_axil_ctrl_wr.wdata[0];
txcq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
end
16'h0308: txcq_base_addr_reg[31:0] <= s_axil_wr.wdata;
16'h030c: txcq_base_addr_reg[63:32] <= s_axil_wr.wdata;
16'h0308: txcq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
16'h030c: txcq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
16'h0400: begin
rxcq_en_reg <= s_axil_wr.wdata[0];
rxcq_size_reg <= s_axil_wr.wdata[19:16];
rxcq_en_reg <= s_axil_ctrl_wr.wdata[0];
rxcq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
end
16'h0408: rxcq_base_addr_reg[31:0] <= s_axil_wr.wdata;
16'h040c: rxcq_base_addr_reg[63:32] <= s_axil_wr.wdata;
16'h0408: rxcq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
16'h040c: rxcq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
default: begin end
endcase
end
if (s_axil_rd.arvalid && !s_axil_rvalid_reg) begin
s_axil_rdata_reg <= '0;
if (s_axil_ctrl_rd.arvalid && !s_axil_ctrl_rvalid_reg) begin
s_axil_ctrl_rdata_reg <= '0;
s_axil_arready_reg <= 1'b1;
s_axil_rvalid_reg <= 1'b1;
s_axil_ctrl_arready_reg <= 1'b1;
s_axil_ctrl_rvalid_reg <= 1'b1;
case ({s_axil_rd.araddr[15:2], 2'b00})
case ({s_axil_ctrl_rd.araddr[15:2], 2'b00})
16'h0100: begin
s_axil_rdata_reg[0] <= txq_en_reg;
s_axil_rdata_reg[19:16] <= txq_size_reg;
s_axil_ctrl_rdata_reg[0] <= txq_en_reg;
s_axil_ctrl_rdata_reg[19:16] <= txq_size_reg;
end
16'h0104: begin
s_axil_rdata_reg[15:0] <= txq_prod_reg;
s_axil_rdata_reg[31:16] <= txq_cons;
s_axil_ctrl_rdata_reg[15:0] <= txq_prod_reg;
s_axil_ctrl_rdata_reg[31:16] <= txq_cons;
end
16'h0108: s_axil_rdata_reg <= txq_base_addr_reg[31:0];
16'h010c: s_axil_rdata_reg <= txq_base_addr_reg[63:32];
16'h0108: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[31:0];
16'h010c: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[63:32];
16'h0200: begin
s_axil_rdata_reg[0] <= rxq_en_reg;
s_axil_rdata_reg[19:16] <= rxq_size_reg;
s_axil_ctrl_rdata_reg[0] <= rxq_en_reg;
s_axil_ctrl_rdata_reg[19:16] <= rxq_size_reg;
end
16'h0204: begin
s_axil_rdata_reg[15:0] <= rxq_prod_reg;
s_axil_rdata_reg[31:16] <= rxq_cons;
s_axil_ctrl_rdata_reg[15:0] <= rxq_prod_reg;
s_axil_ctrl_rdata_reg[31:16] <= rxq_cons;
end
16'h0208: s_axil_rdata_reg <= rxq_base_addr_reg[31:0];
16'h020c: s_axil_rdata_reg <= rxq_base_addr_reg[63:32];
16'h0208: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[31:0];
16'h020c: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[63:32];
16'h0300: begin
s_axil_rdata_reg[0] <= txcq_en_reg;
s_axil_rdata_reg[19:16] <= txcq_size_reg;
s_axil_ctrl_rdata_reg[0] <= txcq_en_reg;
s_axil_ctrl_rdata_reg[19:16] <= txcq_size_reg;
end
16'h0304: s_axil_rdata_reg[15:0] <= txcq_prod;
16'h0308: s_axil_rdata_reg <= txcq_base_addr_reg[31:0];
16'h030c: s_axil_rdata_reg <= txcq_base_addr_reg[63:32];
16'h0304: s_axil_ctrl_rdata_reg[15:0] <= txcq_prod;
16'h0308: s_axil_ctrl_rdata_reg <= txcq_base_addr_reg[31:0];
16'h030c: s_axil_ctrl_rdata_reg <= txcq_base_addr_reg[63:32];
16'h0400: begin
s_axil_rdata_reg[0] <= rxcq_en_reg;
s_axil_rdata_reg[19:16] <= rxcq_size_reg;
s_axil_ctrl_rdata_reg[0] <= rxcq_en_reg;
s_axil_ctrl_rdata_reg[19:16] <= rxcq_size_reg;
end
16'h0404: s_axil_rdata_reg[15:0] <= rxcq_prod;
16'h0408: s_axil_rdata_reg <= rxcq_base_addr_reg[31:0];
16'h040c: s_axil_rdata_reg <= rxcq_base_addr_reg[63:32];
16'h0404: s_axil_ctrl_rdata_reg[15:0] <= rxcq_prod;
16'h0408: s_axil_ctrl_rdata_reg <= rxcq_base_addr_reg[31:0];
16'h040c: s_axil_ctrl_rdata_reg <= rxcq_base_addr_reg[63:32];
default: begin end
endcase
end
if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin
s_apb_dp_ctrl_pready_reg <= 1'b1;
s_apb_dp_ctrl_prdata_reg <= '0;
if (s_apb_dp_ctrl.pwrite) begin
case ({s_apb_dp_ctrl.paddr[15:2], 2'b00})
16'h0100: begin
txq_en_reg <= s_apb_dp_ctrl.pwdata[0];
txq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
end
16'h0104: txq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0];
16'h0108: txq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
16'h010c: txq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
16'h0200: begin
rxq_en_reg <= s_apb_dp_ctrl.pwdata[0];
rxq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
end
16'h0204: rxq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0];
16'h0208: rxq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
16'h020c: rxq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
16'h0300: begin
txcq_en_reg <= s_apb_dp_ctrl.pwdata[0];
txcq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
end
16'h0308: txcq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
16'h030c: txcq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
16'h0400: begin
rxcq_en_reg <= s_apb_dp_ctrl.pwdata[0];
rxcq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
end
16'h0408: rxcq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
16'h040c: rxcq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
default: begin end
endcase
end
case ({s_apb_dp_ctrl.paddr[15:2], 2'b00})
16'h0100: begin
s_apb_dp_ctrl_prdata_reg[0] <= txq_en_reg;
s_apb_dp_ctrl_prdata_reg[19:16] <= txq_size_reg;
end
16'h0104: begin
s_apb_dp_ctrl_prdata_reg[15:0] <= txq_prod_reg;
s_apb_dp_ctrl_prdata_reg[31:16] <= txq_cons;
end
16'h0108: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[31:0];
16'h010c: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[63:32];
16'h0200: begin
s_apb_dp_ctrl_prdata_reg[0] <= rxq_en_reg;
s_apb_dp_ctrl_prdata_reg[19:16] <= rxq_size_reg;
end
16'h0204: begin
s_apb_dp_ctrl_prdata_reg[15:0] <= rxq_prod_reg;
s_apb_dp_ctrl_prdata_reg[31:16] <= rxq_cons;
end
16'h0208: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[31:0];
16'h020c: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[63:32];
16'h0300: begin
s_apb_dp_ctrl_prdata_reg[0] <= txcq_en_reg;
s_apb_dp_ctrl_prdata_reg[19:16] <= txcq_size_reg;
end
16'h0304: s_apb_dp_ctrl_prdata_reg[15:0] <= txcq_prod;
16'h0308: s_apb_dp_ctrl_prdata_reg <= txcq_base_addr_reg[31:0];
16'h030c: s_apb_dp_ctrl_prdata_reg <= txcq_base_addr_reg[63:32];
16'h0400: begin
s_apb_dp_ctrl_prdata_reg[0] <= rxcq_en_reg;
s_apb_dp_ctrl_prdata_reg[19:16] <= rxcq_size_reg;
end
16'h0404: s_apb_dp_ctrl_prdata_reg[15:0] <= rxcq_prod;
16'h0408: s_apb_dp_ctrl_prdata_reg <= rxcq_base_addr_reg[31:0];
16'h040c: s_apb_dp_ctrl_prdata_reg <= rxcq_base_addr_reg[63:32];
default: begin end
endcase
end
if (rst) begin
s_axil_awready_reg <= 1'b0;
s_axil_wready_reg <= 1'b0;
s_axil_bvalid_reg <= 1'b0;
s_axil_ctrl_awready_reg <= 1'b0;
s_axil_ctrl_wready_reg <= 1'b0;
s_axil_ctrl_bvalid_reg <= 1'b0;
s_axil_arready_reg <= 1'b0;
s_axil_rvalid_reg <= 1'b0;
s_axil_ctrl_arready_reg <= 1'b0;
s_axil_ctrl_rvalid_reg <= 1'b0;
s_apb_dp_ctrl_pready_reg <= 1'b0;
end
end