diff options
| author | Eric Dao <eric@erickhangdao.com> | 2025-03-10 17:54:31 -0400 |
|---|---|---|
| committer | Eric Dao <eric@erickhangdao.com> | 2025-03-10 17:54:31 -0400 |
| commit | ab224e2e6ba65f5a369ec392f99cd8845ad06c98 (patch) | |
| tree | a1e757e9341863ed52b8ad4c5a1c45933aab9da4 /python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv | |
| parent | 40da1752f2c8639186b72f6838aa415e854d0b1d (diff) | |
| download | thesis-master.tar.gz thesis-master.tar.bz2 thesis-master.zip | |
Diffstat (limited to 'python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv')
| -rw-r--r-- | python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv b/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv new file mode 100644 index 0000000..0705fef --- /dev/null +++ b/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv @@ -0,0 +1,120 @@ +// Copyright 2020-2024 Intel Corporation. +// +// This software and the related documents are Intel copyrighted materials, +// and your use of them is governed by the express license under which they +// were provided to you ("License"). Unless the License provides otherwise, +// you may not use, modify, copy, publish, distribute, disclose or transmit +// this software or the related documents without Intel's prior written +// permission. +// +// This software and the related documents are provided as is, with no express +// or implied warranties, other than those that are expressly stated in the +// License. + +/** + * dla_ram_arb.sv + * + * arbiter module for full duplex dual port RAM. + * + * Operation: + * The module accepts two read requests, and a single write request. The write + * request takes highest priority. A write request will be sent to either port A or B + * if either are free. Otherwise, if there is a read request on both port A and B, then + * the write will take place on port B and the read request will be ignored. + * The user should check the current_read_a/b outputs to confirm the address that is + * being read. + * + * Assumptions: + * Must be used with full duplex RAM that has a 2-cycle read latency. + * + */ + + `resetall + `undefineall + `default_nettype none + import dla_common_pkg::*; + + module dla_lt_ram_arb #(parameter ADDRESS_WIDTH, parameter DATA_WIDTH) ( + input wire clk, + input wire i_rstn, + //PORT A READ REQUESTS + input wire [ADDRESS_WIDTH-1:0] i_a_address, + input wire i_a_valid_read_req, + + //PORT B READ REQUESTS + input wire [ADDRESS_WIDTH-1:0] i_b_address, + input wire i_b_valid_read_req, + + //WRITE REQUESTS + input wire [ADDRESS_WIDTH-1:0] i_write_address, + input wire i_write_req, + input wire [DATA_WIDTH-1:0] i_write_data, + + //OUTPUTS A + output logic [ADDRESS_WIDTH-1:0] o_arb_address_a, + output logic o_arb_write_valid_a, + output logic [DATA_WIDTH-1:0] o_arb_data_a, + output logic [ADDRESS_WIDTH-1:0] o_current_read_a, // Address of value currently driven on port A (assumes 2-cycle read delay!) + + //OUTPUTS B + output logic [ADDRESS_WIDTH-1:0] o_arb_address_b, + output logic o_arb_write_valid_b, + output logic [DATA_WIDTH-1:0] o_arb_data_b, + output logic [ADDRESS_WIDTH-1:0] o_current_read_b + ); + + logic [ADDRESS_WIDTH-1:0] current_read_a_[1:0]; + logic [ADDRESS_WIDTH-1:0] current_read_b_[1:0]; + + assign o_current_read_a = current_read_a_[0]; + assign o_current_read_b = current_read_b_[0]; + + assign o_arb_data_a = i_write_data; + assign o_arb_data_b = i_write_data; + + + always_ff @(posedge clk) + begin + if (!i_rstn) + begin + current_read_a_ <= '{default: '0}; + current_read_b_ <= '{default: '0}; + end + current_read_a_[1] <= o_arb_address_a; + current_read_a_[0] <= current_read_a_[1]; + + current_read_b_[1] <= o_arb_address_b; + current_read_b_[0] <= current_read_b_[1]; + end + + always_comb begin : arbitrate + o_arb_address_a = i_a_address; + o_arb_write_valid_a = 1'b0; + + o_arb_address_b = i_b_address; + o_arb_write_valid_b = 1'b0; + + + if ((i_write_req == 1'b1 && i_a_valid_read_req == 1'b0) || (i_write_req == 1'b1 && i_a_valid_read_req == 1'b1 && i_a_address == i_write_address)) + begin + // Port A does not have a read request, or read request is for the same address. + o_arb_address_a = i_write_address; + o_arb_write_valid_a = 1'b1; + end + else if ((i_write_req == 1'b1 && i_b_valid_read_req == 1'b0) || (i_write_req == 1'b1 && i_b_valid_read_req == 1'b1 && i_b_address == i_write_address)) + begin + // Port B does not have a read request or read request is for the same address. + o_arb_address_b = i_write_address; + o_arb_write_valid_b = 1'b1; + end + else if (i_write_req == 1'b1 && i_b_valid_read_req == 1'b1 && i_a_valid_read_req == 1'b1 && i_write_address != i_b_address && i_write_address != i_a_address) + begin + // Both A and B have a read request, and there is a write request at a unique address. + // Then send the write request to port B and ignore the read. This disparity will be visible to the user by checking the current_read_b value. + o_arb_address_b = i_write_address; // instead of b_address... + o_arb_write_valid_b = 1'b1; + end + + end + + endmodule //ram_arb |
