From e4e05ed1e3b7329f1ab2ac1a03e472aa752e1a4a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 1 Jun 2021 16:29:52 -0700 Subject: [PATCH 1/2] Update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 302f117c1..b5b927eb2 100644 --- a/README.md +++ b/README.md @@ -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 From 31378c4e85665038fd95e2f139112aa4002a14dc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 2 Jun 2021 17:05:29 -0700 Subject: [PATCH 2/2] Remove string parameters --- rtl/arbiter.v | 46 +++++++++++++++++++------------------ rtl/axis_arb_mux.v | 15 ++++++------ rtl/dma_if_mux.v | 16 ++++++------- rtl/dma_if_mux_rd.v | 15 ++++++------ rtl/dma_if_mux_wr.v | 15 ++++++------ rtl/pcie_axi_dma_desc_mux.v | 15 ++++++------ rtl/pcie_us_msi.v | 7 +++--- rtl/priority_encoder.v | 22 ++++++++++-------- 8 files changed, 81 insertions(+), 70 deletions(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 8b0443fdb..cd55dd3dc 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -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 diff --git a/rtl/axis_arb_mux.v b/rtl/axis_arb_mux.v index 72a3de5e1..ba2618609 100644 --- a/rtl/axis_arb_mux.v +++ b/rtl/axis_arb_mux.v @@ -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), diff --git a/rtl/dma_if_mux.v b/rtl/dma_if_mux.v index 9d2382624..c41a9e586 100644 --- a/rtl/dma_if_mux.v +++ b/rtl/dma_if_mux.v @@ -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), diff --git a/rtl/dma_if_mux_rd.v b/rtl/dma_if_mux_rd.v index 98f13a56d..0ac23353d 100644 --- a/rtl/dma_if_mux_rd.v +++ b/rtl/dma_if_mux_rd.v @@ -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), diff --git a/rtl/dma_if_mux_wr.v b/rtl/dma_if_mux_wr.v index 0ea74df99..6417d54ba 100644 --- a/rtl/dma_if_mux_wr.v +++ b/rtl/dma_if_mux_wr.v @@ -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), diff --git a/rtl/pcie_axi_dma_desc_mux.v b/rtl/pcie_axi_dma_desc_mux.v index 51c4ceadc..f52a9d527 100644 --- a/rtl/pcie_axi_dma_desc_mux.v +++ b/rtl/pcie_axi_dma_desc_mux.v @@ -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), diff --git a/rtl/pcie_us_msi.v b/rtl/pcie_us_msi.v index 2c1be8c21..dd7ce88c9 100644 --- a/rtl/pcie_us_msi.v +++ b/rtl/pcie_us_msi.v @@ -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), diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index 8735a0e37..dd59fa455 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -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