summaryrefslogtreecommitdiff
path: root/rtl/cpu/cpu_imc.sv
diff options
context:
space:
mode:
authorIan M. <ian@aptel.org>2026-09-26 12:16:51 +0000
committerChloe M. <chloe@aptel.org>2026-09-26 13:33:21 +0000
commit08506e7e26ef4f47ad1ed0947c8286a33617c882 (patch)
treeb6024a9e514e65c108cd242f099778446d27b208 /rtl/cpu/cpu_imc.sv
parente3b54015326ae24a29c2c6bdbcc91b164308c068 (diff)
cpu: Add processing domains + IMC
Signed-off-by: Ian M. <ian@aptel.org>
Diffstat (limited to 'rtl/cpu/cpu_imc.sv')
-rw-r--r--rtl/cpu/cpu_imc.sv79
1 files changed, 79 insertions, 0 deletions
diff --git a/rtl/cpu/cpu_imc.sv b/rtl/cpu/cpu_imc.sv
new file mode 100644
index 0000000..2dfca60
--- /dev/null
+++ b/rtl/cpu/cpu_imc.sv
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2026, Apollo Telephone Laboratories.
+// Provided under the BSD-3 clause.
+//
+
+`include "bus/ari.svh"
+
+//
+// The integrated memory controller (IMC) is responsible for making
+// bus transactions using the address operation tag.
+//
+module cpu_imc (
+ input wire clk_i,
+ input wire reset_i,
+ input wire write_en_i,
+ input wire req_i,
+ input wire [PMA_XLEN-1:0] ad_i,
+ input wire [63:0] data_i,
+
+ output AriFrame mb_r_tap_o,
+ output logic op_done_o
+);
+ parameter FSM_STAGE_REQUEST = 0;
+ parameter FSM_STAGE_TX_REQ = 1;
+ parameter FSM_STAGE_WAIT0 = 2;
+ parameter FSM_STAGE_WAIT1 = 3;
+ parameter FSM_STAGE_WAIT2 = 4;
+ parameter FSM_STAGE_WAIT3 = 5;
+ parameter FSM_STAGE_DONE = 6;
+
+ logic [3:0] fsm_stage;
+ logic [3:0] seq;
+ AriAdop adop;
+ AriFrame frame;
+
+ always_ff @(posedge clk_i) begin
+ if (reset_i) begin
+ frame <= 0;
+ fsm_stage <= 0;
+ mb_r_tap_o <= 0;
+ op_done_o <= 0;
+ seq <= 0;
+ end else if (req_i || fsm_stage > FSM_STAGE_REQUEST) begin
+ case (fsm_stage)
+ FSM_STAGE_REQUEST: begin
+ frame.tag <= ARI_ADOP;
+ frame.seq <= seq;
+ frame.payload <= adop;
+ fsm_stage <= FSM_STAGE_TX_REQ;
+ end
+ FSM_STAGE_TX_REQ: begin
+ mb_r_tap_o <= frame;
+ fsm_stage <= FSM_STAGE_WAIT0;
+ end
+
+ // Four cycle wait period as per the spec
+ FSM_STAGE_WAIT0: fsm_stage <= FSM_STAGE_WAIT1;
+ FSM_STAGE_WAIT1: fsm_stage <= FSM_STAGE_WAIT2;
+ FSM_STAGE_WAIT2: fsm_stage <= FSM_STAGE_WAIT3;
+ FSM_STAGE_WAIT3: fsm_stage <= FSM_STAGE_DONE;
+
+ FSM_STAGE_DONE: begin
+ mb_r_tap_o <= 0;
+ op_done_o <= 1;
+ if (!req_i) begin
+ fsm_stage <= FSM_STAGE_REQUEST;
+ op_done_o <= 0;
+ end
+ end
+ endcase
+ end
+ end
+
+ // Continous assignments
+ assign adop.ad = ad_i;
+ assign adop.data = write_en_i ? data_i : 0;
+ assign adop.write_en = write_en_i;
+ assign adop.reserved = 0;
+endmodule