summaryrefslogtreecommitdiff
path: root/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_ram_arb.sv
diff options
context:
space:
mode:
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.sv120
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