diff options
Diffstat (limited to '')
| -rw-r--r-- | rtl/core/control/data.sv | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/rtl/core/control/data.sv b/rtl/core/control/data.sv new file mode 100644 index 0000000..cc83336 --- /dev/null +++ b/rtl/core/control/data.sv @@ -0,0 +1,116 @@ +`include "core/uarch.sv" + +module core_control_data +( + input logic clk, + + input data_decode dec_data, + input snd_decode dec_snd, + input word rd_value_a, + rd_value_b, + input logic mem_ready, + input word q_alu, + q_shifter, + input logic c_shifter, + + input ctrl_cycle cycle, + next_cycle, + input logic issue, + input ptr pc, + input word mem_offset, + input psr_flags flags, + + output alu_op alu, + output word alu_a, + alu_b, + saved_base, + output shifter_control shifter, + output logic[7:0] shifter_shift, + output logic c_in, + trivial_shift, + data_snd_shift_by_reg +); + + logic data_snd_is_imm; + logic[5:0] data_shift_imm; + logic[11:0] data_imm; + + assign trivial_shift = shifter_shift == 0; + + always_comb begin + unique case(cycle) + RD_INDIRECT_SHIFT: shifter_shift = rd_value_b[7:0]; + default: shifter_shift = {2'b00, data_shift_imm}; + endcase + + unique case(cycle) + TRANSFER: alu_a = saved_base; + EXCEPTION: alu_a = {pc, 2'b00}; + default: alu_a = rd_value_a; + endcase + + unique case(cycle) + RD_INDIRECT_SHIFT, WITH_SHIFT: + alu_b = saved_base; + + TRANSFER: + alu_b = mem_offset; + + default: + if(data_snd_is_imm) + alu_b = {{20{1'b0}}, data_imm}; + else + alu_b = rd_value_b; + endcase + end + + always @(posedge clk) + unique0 case(next_cycle) + ISSUE: + if(issue) begin + alu <= dec_data.op; + c_in <= flags.c; + + data_snd_is_imm <= dec_snd.is_imm; + data_snd_shift_by_reg <= dec_snd.shift_by_reg; + data_imm <= dec_snd.imm; + data_shift_imm <= dec_snd.shift_imm; + + shifter.shr <= dec_snd.shr; + shifter.ror <= dec_snd.ror; + shifter.put_carry <= dec_snd.put_carry; + shifter.sign_extend <= dec_snd.sign_extend; + end + + RD_INDIRECT_SHIFT: begin + saved_base <= rd_value_b; + data_snd_shift_by_reg <= 0; + end + + WITH_SHIFT: begin + c_in <= c_shifter; + saved_base <= q_shifter; + end + + TRANSFER: + if(cycle != TRANSFER || mem_ready) + saved_base <= q_alu; + + EXCEPTION: begin + alu <= `ALU_ADD; + data_imm <= 12'd4; + data_snd_is_imm <= 1; + end + endcase + + initial begin + alu = {$bits(alu){1'b0}}; + c_in = 0; + shifter = {$bits(shifter){1'b0}}; + data_imm = {$bits(data_imm){1'b0}}; + data_shift_imm = {$bits(data_shift_imm){1'b0}}; + data_snd_is_imm = 0; + data_snd_shift_by_reg = 0; + end + +endmodule |
