summaryrefslogtreecommitdiff
path: root/rtl/core/regs
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-09-25 15:00:25 -0600
committerAlejandro Soto <alejandro@34project.org>2022-09-25 15:00:25 -0600
commit5dc62fde35731279e5ef4c7b334cb97d4f24f656 (patch)
treee2f73fccc7acd3eabfc51bc4871e396e1ed11a3d /rtl/core/regs
parent601835e33298015cf49f0ab33a7ef3d61b003ad9 (diff)
Implement register file
Diffstat (limited to '')
-rw-r--r--rtl/core/regs/file.sv24
-rw-r--r--rtl/core/regs/map.sv32
-rw-r--r--rtl/core/regs/regs.sv76
3 files changed, 132 insertions, 0 deletions
diff --git a/rtl/core/regs/file.sv b/rtl/core/regs/file.sv
new file mode 100644
index 0000000..1b10682
--- /dev/null
+++ b/rtl/core/regs/file.sv
@@ -0,0 +1,24 @@
+`include "core/uarch.sv"
+
+module core_reg_file
+(
+ input logic clk,
+ input reg_index rd_index,
+ wr_index,
+ input logic wr_enable,
+ input word wr_value,
+
+ output word rd_value
+);
+
+ // Ver comentario en uarch.sv
+ word file[30];
+
+ always @(posedge clk)
+ if(wr_enable)
+ file[rd_index] <= wr_value;
+
+ always @(posedge clk)
+ rd_value <= wr_enable & (rd_index == wr_index) ? wr_value : file[rd_index];
+
+endmodule
diff --git a/rtl/core/regs/map.sv b/rtl/core/regs/map.sv
new file mode 100644
index 0000000..b4da988
--- /dev/null
+++ b/rtl/core/regs/map.sv
@@ -0,0 +1,32 @@
+`include "core/isa.sv"
+`include "core/psr.sv"
+`include "core/uarch.sv"
+
+module core_reg_map
+(
+ input reg_num r,
+ input psr_mode mode,
+ output logic is_pc,
+ output reg_index index
+);
+
+ reg_index usr;
+ assign usr = {1'b0, r};
+
+ always_comb begin
+ index = 5'bxxxxx;
+ is_pc = r == `R15;
+
+ if(~is_pc)
+ unique case(mode)
+ `MODE_USR, `MODE_SYS: index = usr;
+ `MODE_FIQ: index = r >= 8 ? usr + 7 : usr;
+ `MODE_IRQ: index = r >= 13 ? usr + 9 : usr;
+ `MODE_UND: index = r >= 13 ? usr + 11 : usr;
+ `MODE_ABT: index = r >= 13 ? usr + 13 : usr;
+ `MODE_SVC: index = r >= 13 ? usr + 15 : usr;
+ default: ;
+ endcase
+ end
+
+endmodule
diff --git a/rtl/core/regs/regs.sv b/rtl/core/regs/regs.sv
new file mode 100644
index 0000000..5f51faa
--- /dev/null
+++ b/rtl/core/regs/regs.sv
@@ -0,0 +1,76 @@
+`include "core/isa.sv"
+`include "core/psr.sv"
+
+module core_regs
+(
+ input logic clk,
+ input reg_num rd_r_a,
+ rd_r_b,
+ wr_r,
+ input psr_mode rd_mode,
+ wr_mode,
+ input logic wr_enable,
+ input word wr_value,
+ input ptr pc_visible,
+
+ output word rd_value_a,
+ rd_value_b,
+ output logic branch
+);
+
+ /* Las Cyclone V no tienen bloques de memoria con al menos dos puertos de
+ * lectura y uno de escritura (tres puertos), lo más que tienen son bloques
+ * de dos puertos en total. Podemos ponerle cinta a esto con dos copias
+ * sincronizadas del archivo de registros.
+ */
+
+ logic rd_pc_a, rd_pc_b, wr_pc, file_wr_enable;
+ reg_index rd_index_a, rd_index_b, wr_index;
+ word pc_word, file_rd_value_a, file_rd_value_b;
+
+ assign pc_word = {pc_visible, 2'b00};
+ assign rd_value_a = rd_pc_a ? pc_word : file_rd_value_a;
+ assign rd_value_b = rd_pc_b ? pc_word : file_rd_value_b;
+ assign branch = wr_enable & wr_pc;
+
+ core_reg_file a
+ (
+ .rd_index(rd_index_a),
+ .rd_value(file_rd_value_a),
+ .wr_enable(file_wr_enable),
+ .*
+ );
+
+ core_reg_file b
+ (
+ .rd_index(rd_index_b),
+ .rd_value(file_rd_value_b),
+ .wr_enable(wr_enable & ~wr_pc),
+ .*
+ );
+
+ core_reg_map map_rd_a
+ (
+ .r(rd_r_a),
+ .mode(rd_mode),
+ .is_pc(rd_pc_a),
+ .index(rd_index_a)
+ );
+
+ core_reg_map map_rd_b
+ (
+ .r(rd_r_b),
+ .mode(rd_mode),
+ .is_pc(rd_pc_b),
+ .index(rd_index_b)
+ );
+
+ core_reg_map map_wr
+ (
+ .r(wr_r),
+ .mode(wr_mode),
+ .is_pc(wr_pc),
+ .index(wr_index)
+ );
+
+endmodule