summaryrefslogtreecommitdiff
path: root/rtl/core/control
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/core/control')
-rw-r--r--rtl/core/control/control.sv68
-rw-r--r--rtl/core/control/ldst/ldst.sv90
2 files changed, 98 insertions, 60 deletions
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index 629e1d9..d214525 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -54,14 +54,7 @@ module core_control
coproc
);
- logic ldst, ldst_pre, ldst_increment, ldst_writeback, pop_valid;
- word mem_offset;
- reg_num popped_upper, popped_lower, popped;
- reg_list mem_regs, next_regs_upper, next_regs_lower;
-
assign reg_mode = `MODE_SVC; //TODO
- assign mem_data_wr = rd_value_b;
- assign popped = ldst_increment ? popped_lower : popped_upper;
ctrl_cycle cycle, next_cycle;
@@ -90,14 +83,13 @@ module core_control
.*
);
- core_control_ldst_pop ctrl_ldst_pop
+ word mem_offset;
+ logic ldst, ldst_writeback, pop_valid;
+ reg_num popped;
+
+ core_control_ldst ctrl_ldst
(
- .regs(mem_regs),
- .valid(pop_valid),
- .next_upper(next_regs_upper),
- .next_lower(next_regs_lower),
- .pop_upper(popped_upper),
- .pop_lower(popped_lower)
+ .*
);
core_control_branch ctrl_branch
@@ -132,64 +124,20 @@ module core_control
always_ff @(posedge clk) begin
wb_alu_flags <= alu_flags;
- unique case(next_cycle)
+ unique0 case(next_cycle)
ISSUE:
if(issue) begin
- // TODO: dec_ldst.unprivileged/user_regs
- // TODO: byte/halfword sizes
- ldst <= dec.ldst;
- ldst_pre <= dec_ldst.pre_indexed;
- ldst_increment <= dec_ldst.increment;
- ldst_writeback <= dec_ldst.writeback;
-
mul <= dec.mul;
mul_add <= dec_mul.add;
mul_long <= dec_mul.long_mul;
mul_signed <= dec_mul.signed_mul;
coproc <= dec.coproc;
-
- mem_regs <= dec_ldst.regs;
- mem_write <= !dec_ldst.load;
end
-
- RD_INDIRECT_SHIFT: ;
-
- WITH_SHIFT: ;
-
- TRANSFER: begin
- if(cycle != TRANSFER) begin
- ldst <= 0;
- mem_offset <= alu_b;
- end
-
- if(cycle != TRANSFER || mem_ready) begin
- mem_regs <= ldst_increment ? next_regs_lower : next_regs_upper;
- mem_addr <= ldst_pre ? q_alu[31:2] : alu_a[31:2];
- end
-
- mem_start <= cycle != TRANSFER || (mem_ready && pop_valid);
- end
-
- BASE_WRITEBACK: ;
-
- EXCEPTION: ;
endcase
end
- initial begin
+ initial
wb_alu_flags = 4'b0000;
- ldst = 0;
- ldst_pre = 0;
- ldst_writeback = 0;
- ldst_increment = 0;
-
- mem_addr = 30'b0;
- mem_write = 0;
- mem_start = 0;
- mem_regs = 16'b0;
- mem_offset = 0;
- end
-
endmodule
diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv
new file mode 100644
index 0000000..daea893
--- /dev/null
+++ b/rtl/core/control/ldst/ldst.sv
@@ -0,0 +1,90 @@
+`include "core/uarch.sv"
+
+module core_control_ldst
+(
+ input logic clk,
+
+ input datapath_decode dec,
+ input ldst_decode dec_ldst,
+ input logic issue,
+ mem_ready,
+ input word rd_value_b,
+ q_alu,
+
+ input ctrl_cycle cycle,
+ next_cycle,
+ input word alu_a,
+ alu_b,
+
+ output ptr mem_addr,
+ output word mem_data_wr,
+ mem_offset,
+ output logic mem_start,
+ mem_write,
+ pop_valid,
+ ldst,
+ ldst_writeback,
+ output reg_num popped
+);
+
+ logic ldst_pre, ldst_increment;
+ reg_num popped_upper, popped_lower;
+ reg_list mem_regs, next_regs_upper, next_regs_lower;
+
+ assign mem_data_wr = rd_value_b;
+ assign popped = ldst_increment ? popped_lower : popped_upper;
+
+ core_control_ldst_pop pop
+ (
+ .regs(mem_regs),
+ .valid(pop_valid),
+ .next_upper(next_regs_upper),
+ .next_lower(next_regs_lower),
+ .pop_upper(popped_upper),
+ .pop_lower(popped_lower)
+ );
+
+ always_ff @(posedge clk)
+ unique0 case(next_cycle)
+ ISSUE:
+ if(issue) begin
+ // TODO: dec_ldst.unprivileged/user_regs
+ // TODO: byte/halfword sizes
+ ldst <= dec.ldst;
+ ldst_pre <= dec_ldst.pre_indexed;
+ ldst_increment <= dec_ldst.increment;
+ ldst_writeback <= dec_ldst.writeback;
+
+ mem_regs <= dec_ldst.regs;
+ mem_write <= !dec_ldst.load;
+ end
+
+ TRANSFER: begin
+ if(cycle != TRANSFER) begin
+ ldst <= 0;
+ mem_offset <= alu_b;
+ end
+
+ if(cycle != TRANSFER || mem_ready) begin
+ mem_regs <= ldst_increment ? next_regs_lower : next_regs_upper;
+ mem_addr <= ldst_pre ? q_alu[31:2] : alu_a[31:2];
+ end
+
+ mem_start <= cycle != TRANSFER || (mem_ready && pop_valid);
+ end
+ endcase
+
+ initial begin
+ ldst = 0;
+ ldst_pre = 0;
+ ldst_writeback = 0;
+ ldst_increment = 0;
+
+ mem_addr = {$bits(mem_addr){1'b0}};
+ mem_write = 0;
+ mem_start = 0;
+ mem_regs = {$bits(mem_regs){1'b0}};
+ mem_offset = 0;
+ end
+
+endmodule