mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
merged changes in pcie
This commit is contained in:
commit
bea7ff909f
@ -13,6 +13,7 @@ lite bridges, a simple PCIe AXI DMA engine, and a flexible, high-performance
|
||||
DMA subsystem. Currently supports operation with the Xilinx UltraScale and
|
||||
UltraScale+ PCIe hard IP cores with interfaces between 64 and 512 bits.
|
||||
Includes full cocotb testbenches that utilize
|
||||
[cocotbext-pcie](https://github.com/alexforencich/cocotbext-pcie) and
|
||||
[cocotbext-axi](https://github.com/alexforencich/cocotbext-axi).
|
||||
|
||||
## Documentation
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
Copyright (c) 2014-2021 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -32,12 +32,14 @@ THE SOFTWARE.
|
||||
module arbiter #
|
||||
(
|
||||
parameter PORTS = 4,
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter TYPE = "PRIORITY",
|
||||
// block type: "NONE", "REQUEST", "ACKNOWLEDGE"
|
||||
parameter BLOCK = "NONE",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "LOW"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// blocking arbiter enable
|
||||
parameter ARB_BLOCK = 0,
|
||||
// block on acknowledge assert when nonzero, request deassert when 0
|
||||
parameter ARB_BLOCK_ACK = 1,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 0
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -65,7 +67,7 @@ wire [PORTS-1:0] request_mask;
|
||||
|
||||
priority_encoder #(
|
||||
.WIDTH(PORTS),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
priority_encoder_inst (
|
||||
.input_unencoded(request),
|
||||
@ -82,7 +84,7 @@ wire [PORTS-1:0] masked_request_mask;
|
||||
|
||||
priority_encoder #(
|
||||
.WIDTH(PORTS),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
priority_encoder_masked (
|
||||
.input_unencoded(request & mask_reg),
|
||||
@ -97,41 +99,41 @@ always @* begin
|
||||
grant_encoded_next = 0;
|
||||
mask_next = mask_reg;
|
||||
|
||||
if (BLOCK == "REQUEST" && grant_reg & request) begin
|
||||
if (ARB_BLOCK && !ARB_BLOCK_ACK && grant_reg & request) begin
|
||||
// granted request still asserted; hold it
|
||||
grant_valid_next = grant_valid_reg;
|
||||
grant_next = grant_reg;
|
||||
grant_encoded_next = grant_encoded_reg;
|
||||
end else if (BLOCK == "ACKNOWLEDGE" && grant_valid && !(grant_reg & acknowledge)) begin
|
||||
end else if (ARB_BLOCK && ARB_BLOCK_ACK && grant_valid && !(grant_reg & acknowledge)) begin
|
||||
// granted request not yet acknowledged; hold it
|
||||
grant_valid_next = grant_valid_reg;
|
||||
grant_next = grant_reg;
|
||||
grant_encoded_next = grant_encoded_reg;
|
||||
end else if (request_valid) begin
|
||||
if (TYPE == "PRIORITY") begin
|
||||
grant_valid_next = 1;
|
||||
grant_next = request_mask;
|
||||
grant_encoded_next = request_index;
|
||||
end else if (TYPE == "ROUND_ROBIN") begin
|
||||
if (ARB_TYPE_ROUND_ROBIN) begin
|
||||
if (masked_request_valid) begin
|
||||
grant_valid_next = 1;
|
||||
grant_next = masked_request_mask;
|
||||
grant_encoded_next = masked_request_index;
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index);
|
||||
end else begin
|
||||
if (ARB_LSB_HIGH_PRIORITY) begin
|
||||
mask_next = {PORTS{1'b1}} << (masked_request_index + 1);
|
||||
end else begin
|
||||
mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index);
|
||||
end
|
||||
end else begin
|
||||
grant_valid_next = 1;
|
||||
grant_next = request_mask;
|
||||
grant_encoded_next = request_index;
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
mask_next = {PORTS{1'b1}} >> (PORTS - request_index);
|
||||
end else begin
|
||||
if (ARB_LSB_HIGH_PRIORITY) begin
|
||||
mask_next = {PORTS{1'b1}} << (request_index + 1);
|
||||
end else begin
|
||||
mask_next = {PORTS{1'b1}} >> (PORTS - request_index);
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
grant_valid_next = 1;
|
||||
grant_next = request_mask;
|
||||
grant_encoded_next = request_index;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -51,10 +51,10 @@ module axis_arb_mux #
|
||||
parameter USER_ENABLE = 1,
|
||||
// tuser signal width
|
||||
parameter USER_WIDTH = 1,
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter ARB_TYPE = "PRIORITY",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "HIGH"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -119,9 +119,10 @@ wire [USER_WIDTH-1:0] current_s_tuser = s_axis_tuser[grant_encoded*USER_WIDTH +
|
||||
// arbiter instance
|
||||
arbiter #(
|
||||
.PORTS(S_COUNT),
|
||||
.TYPE(ARB_TYPE),
|
||||
.BLOCK("ACKNOWLEDGE"),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_BLOCK(1),
|
||||
.ARB_BLOCK_ACK(1),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
arb_inst (
|
||||
.clk(clk),
|
||||
|
@ -57,10 +57,10 @@ module dma_if_mux #
|
||||
// Output tag field width (towards DMA module)
|
||||
// Additional bits required for response routing
|
||||
parameter M_TAG_WIDTH = S_TAG_WIDTH+$clog2(PORTS),
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter ARB_TYPE = "PRIORITY",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "HIGH"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -184,8 +184,8 @@ dma_if_mux_rd #(
|
||||
.LEN_WIDTH(LEN_WIDTH),
|
||||
.S_TAG_WIDTH(S_TAG_WIDTH),
|
||||
.M_TAG_WIDTH(M_TAG_WIDTH),
|
||||
.ARB_TYPE(ARB_TYPE),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
dma_if_mux_rd_inst (
|
||||
.clk(clk),
|
||||
@ -261,8 +261,8 @@ dma_if_mux_wr #(
|
||||
.LEN_WIDTH(LEN_WIDTH),
|
||||
.S_TAG_WIDTH(S_TAG_WIDTH),
|
||||
.M_TAG_WIDTH(M_TAG_WIDTH),
|
||||
.ARB_TYPE(ARB_TYPE),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
dma_if_mux_wr_inst (
|
||||
.clk(clk),
|
||||
|
@ -57,10 +57,10 @@ module dma_if_mux_rd #
|
||||
// Output tag field width (towards DMA module)
|
||||
// Additional bits required for response routing
|
||||
parameter M_TAG_WIDTH = S_TAG_WIDTH+$clog2(PORTS),
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter ARB_TYPE = "PRIORITY",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "HIGH"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -173,9 +173,10 @@ wire current_s_desc_ready = s_axis_read_desc_ready[gra
|
||||
// arbiter instance
|
||||
arbiter #(
|
||||
.PORTS(PORTS),
|
||||
.TYPE(ARB_TYPE),
|
||||
.BLOCK("ACKNOWLEDGE"),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_BLOCK(1),
|
||||
.ARB_BLOCK_ACK(1),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
arb_inst (
|
||||
.clk(clk),
|
||||
|
@ -57,10 +57,10 @@ module dma_if_mux_wr #
|
||||
// Output tag field width (towards DMA module)
|
||||
// Additional bits required for response routing
|
||||
parameter M_TAG_WIDTH = S_TAG_WIDTH+$clog2(PORTS),
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter ARB_TYPE = "PRIORITY",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "HIGH"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -174,9 +174,10 @@ wire current_s_desc_ready = s_axis_write_desc_ready[gr
|
||||
// arbiter instance
|
||||
arbiter #(
|
||||
.PORTS(PORTS),
|
||||
.TYPE(ARB_TYPE),
|
||||
.BLOCK("ACKNOWLEDGE"),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_BLOCK(1),
|
||||
.ARB_BLOCK_ACK(1),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
arb_inst (
|
||||
.clk(clk),
|
||||
|
@ -44,10 +44,10 @@ module pcie_axi_dma_desc_mux #
|
||||
// Output tag field width (towards DMA module)
|
||||
// Additional bits required for response routing
|
||||
parameter M_TAG_WIDTH = S_TAG_WIDTH+$clog2(PORTS),
|
||||
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
|
||||
parameter ARB_TYPE = "PRIORITY",
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "HIGH"
|
||||
// select round robin arbitration
|
||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||
// LSB priority selection
|
||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@ -125,9 +125,10 @@ wire current_s_desc_ready = s_axis_desc_ready[grant_e
|
||||
// arbiter instance
|
||||
arbiter #(
|
||||
.PORTS(PORTS),
|
||||
.TYPE(ARB_TYPE),
|
||||
.BLOCK("ACKNOWLEDGE"),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||
.ARB_BLOCK(1),
|
||||
.ARB_BLOCK_ACK(1),
|
||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||
)
|
||||
arb_inst (
|
||||
.clk(clk),
|
||||
|
@ -94,9 +94,10 @@ wire grant_valid;
|
||||
// arbiter instance
|
||||
arbiter #(
|
||||
.PORTS(MSI_COUNT),
|
||||
.TYPE("ROUND_ROBIN"),
|
||||
.BLOCK("ACKNOWLEDGE"),
|
||||
.LSB_PRIORITY("HIGH")
|
||||
.ARB_TYPE_ROUND_ROBIN(1),
|
||||
.ARB_BLOCK(1),
|
||||
.ARB_BLOCK_ACK(1),
|
||||
.ARB_LSB_HIGH_PRIORITY(1)
|
||||
)
|
||||
arb_inst (
|
||||
.clk(clk),
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
Copyright (c) 2014-2021 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -32,8 +32,8 @@ THE SOFTWARE.
|
||||
module priority_encoder #
|
||||
(
|
||||
parameter WIDTH = 4,
|
||||
// LSB priority: "LOW", "HIGH"
|
||||
parameter LSB_PRIORITY = "LOW"
|
||||
// LSB priority selection
|
||||
parameter LSB_HIGH_PRIORITY = 0
|
||||
)
|
||||
(
|
||||
input wire [WIDTH-1:0] input_unencoded,
|
||||
@ -57,10 +57,12 @@ generate
|
||||
// process input bits; generate valid bit and encoded bit for each pair
|
||||
for (n = 0; n < W/2; n = n + 1) begin : loop_in
|
||||
assign stage_valid[0][n] = |input_padded[n*2+1:n*2];
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
assign stage_enc[0][n] = input_padded[n*2+1];
|
||||
end else begin
|
||||
if (LSB_HIGH_PRIORITY) begin
|
||||
// bit 0 is highest priority
|
||||
assign stage_enc[0][n] = !input_padded[n*2+0];
|
||||
end else begin
|
||||
// bit 0 is lowest priority
|
||||
assign stage_enc[0][n] = input_padded[n*2+1];
|
||||
end
|
||||
end
|
||||
|
||||
@ -68,10 +70,12 @@ generate
|
||||
for (l = 1; l < LEVELS; l = l + 1) begin : loop_levels
|
||||
for (n = 0; n < W/(2*2**l); n = n + 1) begin : loop_compress
|
||||
assign stage_valid[l][n] = |stage_valid[l-1][n*2+1:n*2];
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+1] ? {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]} : {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]};
|
||||
end else begin
|
||||
if (LSB_HIGH_PRIORITY) begin
|
||||
// bit 0 is highest priority
|
||||
assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+0] ? {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]} : {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]};
|
||||
end else begin
|
||||
// bit 0 is lowest priority
|
||||
assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+1] ? {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]} : {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user