1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

Implement flow control in UltraScale shim

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2022-07-26 14:01:00 -07:00
parent a5fe40cd42
commit 0d9b1d0fb0
5 changed files with 108 additions and 52 deletions

View File

@ -135,18 +135,7 @@ module example_core_pcie_us #
input wire s_axis_rq_seq_num_valid_1,
/*
* Flow control
*/
input wire [7:0] cfg_fc_ph,
input wire [11:0] cfg_fc_pd,
input wire [7:0] cfg_fc_nph,
input wire [11:0] cfg_fc_npd,
input wire [7:0] cfg_fc_cplh,
input wire [11:0] cfg_fc_cpld,
output wire [2:0] cfg_fc_sel,
/*
* Configuration interface
* Configuration management interface
*/
output wire [9:0] cfg_mgmt_addr,
output wire [7:0] cfg_mgmt_function_number,
@ -158,7 +147,24 @@ module example_core_pcie_us #
input wire cfg_mgmt_read_write_done,
/*
* Interrupt interface
* Configuration status interface
*/
input wire [2:0] cfg_max_read_req,
input wire [2:0] cfg_max_payload,
/*
* Configuration flow control interface
*/
input wire [7:0] cfg_fc_ph,
input wire [11:0] cfg_fc_pd,
input wire [7:0] cfg_fc_nph,
input wire [11:0] cfg_fc_npd,
input wire [7:0] cfg_fc_cplh,
input wire [11:0] cfg_fc_cpld,
output wire [2:0] cfg_fc_sel,
/*
* Configuration interrupt interface
*/
input wire [3:0] cfg_interrupt_msix_enable,
input wire [3:0] cfg_interrupt_msix_mask,
@ -173,12 +179,6 @@ module example_core_pcie_us #
input wire cfg_interrupt_msix_fail,
output wire [7:0] cfg_interrupt_msi_function_number,
/*
* Configuration
*/
input wire [2:0] cfg_max_read_req,
input wire [2:0] cfg_max_payload,
/*
* Status
*/
@ -342,18 +342,7 @@ pcie_us_if_inst (
.s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1),
/*
* Flow control
*/
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
/*
* Configuration interface
* Configuration management interface
*/
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
@ -365,7 +354,24 @@ pcie_us_if_inst (
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
/*
* Interrupt interface
* Configuration status interface
*/
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
/*
* Configuration flow control interface
*/
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
/*
* Configuration interrupt interface
*/
.cfg_interrupt_msi_enable(),
.cfg_interrupt_msi_vf_enable(),

View File

@ -139,18 +139,7 @@ module pcie_us_if #
input wire s_axis_rq_seq_num_valid_1,
/*
* Flow control
*/
input wire [7:0] cfg_fc_ph,
input wire [11:0] cfg_fc_pd,
input wire [7:0] cfg_fc_nph,
input wire [11:0] cfg_fc_npd,
input wire [7:0] cfg_fc_cplh,
input wire [11:0] cfg_fc_cpld,
output wire [2:0] cfg_fc_sel,
/*
* Configuration interface
* Configuration management interface
*/
output wire [9:0] cfg_mgmt_addr,
output wire [7:0] cfg_mgmt_function_number,
@ -162,7 +151,24 @@ module pcie_us_if #
input wire cfg_mgmt_read_write_done,
/*
* Interrupt interface
* Configuration status interface
*/
output wire [2:0] cfg_max_payload,
output wire [2:0] cfg_max_read_req,
/*
* Configuration flow control interface
*/
input wire [7:0] cfg_fc_ph,
input wire [11:0] cfg_fc_pd,
input wire [7:0] cfg_fc_nph,
input wire [11:0] cfg_fc_npd,
input wire [7:0] cfg_fc_cplh,
input wire [11:0] cfg_fc_cpld,
output wire [2:0] cfg_fc_sel,
/*
* Configuration interrupt interface
*/
input wire [3:0] cfg_interrupt_msi_enable,
input wire [7:0] cfg_interrupt_msi_vf_enable,
@ -405,7 +411,20 @@ pcie_us_if_rq_inst
* Transmit sequence number output (DMA write request)
*/
.m_axis_wr_req_tx_seq_num(m_axis_wr_req_tx_seq_num),
.m_axis_wr_req_tx_seq_num_valid(m_axis_wr_req_tx_seq_num_valid)
.m_axis_wr_req_tx_seq_num_valid(m_axis_wr_req_tx_seq_num_valid),
/*
* Flow control
*/
.tx_fc_ph_av(tx_fc_ph_av),
.tx_fc_pd_av(tx_fc_pd_av),
.tx_fc_nph_av(tx_fc_nph_av),
.tx_fc_npd_av(tx_fc_npd_av),
/*
* Configuration
*/
.max_payload_size(cfg_max_payload)
);
pcie_us_if_cq #(

View File

@ -110,7 +110,20 @@ module pcie_us_if_rq #
* Transmit sequence number output (DMA write request)
*/
output wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_wr_req_tx_seq_num,
output wire [TX_SEQ_NUM_COUNT-1:0] m_axis_wr_req_tx_seq_num_valid
output wire [TX_SEQ_NUM_COUNT-1:0] m_axis_wr_req_tx_seq_num_valid,
/*
* Flow control
*/
input wire [7:0] tx_fc_ph_av,
input wire [11:0] tx_fc_pd_av,
input wire [7:0] tx_fc_nph_av,
input wire [11:0] tx_fc_npd_av,
/*
* Configuration
*/
input wire [2:0] max_payload_size
);
parameter TLP_DATA_WIDTH_BYTES = TLP_DATA_WIDTH/8;
@ -207,6 +220,10 @@ localparam [3:0]
REQ_MSG_VENDOR = 4'b1101,
REQ_MSG_ATS = 4'b1110;
reg [8:0] max_payload_size_fc_reg = 9'd0;
reg have_p_credit_reg = 1'b0;
reg have_np_credit_reg = 1'b0;
reg frame_reg = 1'b0, frame_next, frame_cyc;
reg tlp_hdr1_reg = 1'b0, tlp_hdr1_next, tlp_hdr1_cyc;
reg tlp_hdr2_reg = 1'b0, tlp_hdr2_next, tlp_hdr2_cyc;
@ -291,6 +308,8 @@ reg [SEG_SEL_WIDTH+1-1:0] fifo_read_seg_count[0:PORTS-1];
reg [INT_TLP_SEG_COUNT-1:0] fifo_tlp_extra[0:PORTS-1];
wire [PORTS-1:0] port_have_credit;
// read requests
pcie_tlp_fifo_raw #(
.DEPTH((1024/4)*2),
@ -359,6 +378,8 @@ rd_req_fifo_inst (
assign fifo_tlp_data[0] = 0;
assign fifo_tlp_strb[0] = 0;
assign port_have_credit[0] = have_np_credit_reg;
// write requests
pcie_tlp_fifo_raw #(
.DEPTH((1024/4)*2),
@ -424,6 +445,8 @@ wr_req_fifo_inst (
.watermark()
);
assign port_have_credit[1] = have_p_credit_reg;
integer port, cur_port, seg, cur_seg, lane;
always @* begin
@ -504,7 +527,7 @@ always @* begin
tlp_split1_cyc = 1'b0;
tlp_split2_cyc = 1'b0;
for (port = 0; port < PORTS; port = port + 1) begin
if (port_seg_valid[cur_port][0] && !frame_cyc) begin
if (port_seg_valid[cur_port][0] && port_have_credit[cur_port] && !frame_cyc) begin
// select port, set frame
frame_cyc = 1'b1;
port_cyc = cur_port;
@ -844,9 +867,11 @@ always @* begin
end
end
integer i;
always @(posedge clk) begin
max_payload_size_fc_reg <= 9'd8 << (max_payload_size > 5 ? 5 : max_payload_size);
have_p_credit_reg <= (tx_fc_ph_av > 4) && (tx_fc_pd_av > (max_payload_size_fc_reg << 1));
have_np_credit_reg <= tx_fc_nph_av > 4;
frame_reg <= frame_next;
tlp_hdr1_reg <= tlp_hdr1_next;
tlp_hdr2_reg <= tlp_hdr2_next;

View File

@ -166,8 +166,8 @@ class TB(object):
# cfg_phy_link_status
# cfg_negotiated_width
# cfg_current_speed
# cfg_max_payload
# cfg_max_read_req
cfg_max_payload=dut.cfg_max_payload,
cfg_max_read_req=dut.cfg_max_read_req,
# cfg_function_status
# cfg_vf_status
# cfg_function_power_state

View File

@ -71,6 +71,12 @@ class TB(object):
dut.s_axis_rq_seq_num_1.setimmediatevalue(0)
dut.s_axis_rq_seq_num_valid_1.setimmediatevalue(0)
dut.tx_fc_ph_av.setimmediatevalue(0x80)
dut.tx_fc_pd_av.setimmediatevalue(0x800)
dut.tx_fc_nph_av.setimmediatevalue(0x80)
dut.tx_fc_npd_av.setimmediatevalue(0x800)
dut.max_payload_size.setimmediatevalue(0)
def set_idle_generator(self, generator=None):
if generator:
self.rd_req_source.set_pause_generator(generator())