summaryrefslogtreecommitdiff
path: root/rtl/core/decode
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-11-06 20:14:13 -0600
committerAlejandro Soto <alejandro@34project.org>2022-11-07 13:31:15 -0600
commitf78de55eef2e805e459064005daa08c7697d2273 (patch)
tree805d162231c9d41a948bdf9cece811165f1fe1a8 /rtl/core/decode
parent8315f5f3ea43150d250aa16575ab274913f93d2a (diff)
Split decode mux logic out of decode.sv
Diffstat (limited to '')
-rw-r--r--rtl/core/decode/decode.sv181
-rw-r--r--rtl/core/decode/mux.sv239
2 files changed, 248 insertions, 172 deletions
diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv
index bf870b5..f8042a9 100644
--- a/rtl/core/decode/decode.sv
+++ b/rtl/core/decode/decode.sv
@@ -16,9 +16,6 @@ module core_decode
output coproc_decode coproc_ctrl
);
- logic execute, undefined, explicit_cond, conditional, writeback,
- update_flags, branch, ldst, mul, coproc, spsr, psr_write;
-
assign ctrl.execute = execute;
assign ctrl.undefined = undefined;
assign ctrl.conditional = conditional;
@@ -32,10 +29,18 @@ module core_decode
assign psr_ctrl.write = psr_write;
assign psr_ctrl.update_flags = update_flags;
+ logic execute, undefined, conditional, writeback, update_flags,
+ branch, ldst, mul, coproc, spsr, psr_write;
+
+ core_decode_mux mux
+ (
+ .*
+ );
+
//TODO
logic restore_spsr;
- logic cond_undefined, cond_execute;
+ logic cond_undefined, cond_execute, explicit_cond;
core_decode_conds conds
(
@@ -174,172 +179,4 @@ module core_decode
.*
);
- always_comb begin
- mul = 0;
- ldst = 0;
- branch = 0;
- coproc = 0;
- execute = cond_execute;
- undefined = cond_undefined;
- writeback = 0;
- conditional = explicit_cond;
-
- spsr = 0;
- psr_write = 0;
- update_flags = 0;
-
- data_ctrl = {($bits(data_ctrl)){1'bx}};
- data_ctrl.uses_rn = 1;
-
- snd_ctrl = {$bits(snd_ctrl){1'bx}};
- snd_ctrl.shr = 0;
- snd_ctrl.ror = 0;
- snd_ctrl.is_imm = 1;
- snd_ctrl.shift_imm = {$bits(snd_ctrl.shift_imm){1'b0}};
- snd_ctrl.shift_by_reg = 0;
-
- snd_is_imm = 1'bx;
- snd_ror_if_imm = 1'bx;
- snd_shift_by_reg_if_reg = 1'bx;
-
- ldst_addr = {($bits(ldst_addr)){1'bx}};
- ldst_ctrl = {($bits(ldst_ctrl)){1'bx}};
-
- // El orden de los casos es importante, NO CAMBIAR
- priority casez(insn `FIELD_OP)
- `GROUP_B: begin
- branch = 1;
- if(branch_link) begin
- data_ctrl.op = `ALU_SUB;
- data_ctrl.rd = `R14;
- data_ctrl.rn = `R15;
- snd_ctrl.imm = 12'd4;
- writeback = 1;
- end
- end
-
- `GROUP_MUL: begin
- mul = 1;
-
- data_ctrl.rd = mul_rd;
- data_ctrl.rn = mul_rs;
-
- snd_ctrl.is_imm = 0;
- snd_ctrl.r = mul_rm;
-
- writeback = 1;
- update_flags = mul_update_flags;
- end
-
- `GROUP_ALU: begin
- snd_is_imm = data_is_imm;
- snd_ror_if_imm = 1;
- snd_shift_by_reg_if_reg = data_shift_by_reg_if_reg;
-
- snd_ctrl = snd;
- data_ctrl = data;
-
- writeback = data_writeback;
- update_flags = data_update_flags;
- restore_spsr = data_restore_spsr;
- undefined = undefined | snd_undefined;
- end
-
- `GROUP_LDST_SINGLE_IMM, `GROUP_LDST_SINGLE_REG: begin
- snd_is_imm = ldst_single_is_imm;
- snd_ror_if_imm = 0;
- snd_shift_by_reg_if_reg = 0;
-
- snd_ctrl = snd;
- ldst_ctrl = ldst_single;
- ldst_addr = ldst_single;
-
- undefined = undefined | snd_undefined;
- end
-
- `GROUP_LDST_MISC_IMM, `GROUP_LDST_MISC_REG:
- priority casez(insn `FIELD_OP)
- `INSN_LDRB, `INSN_LDRSB, `INSN_LDRSH, `INSN_STRH: begin
- ldst_ctrl = ldst_misc;
- ldst_addr = ldst_misc;
-
- snd_ctrl.r = ldst_misc_off_reg;
- snd_ctrl.imm = {4'b0, ldst_misc_off_imm};
- snd_ctrl.is_imm = !ldst_misc_off_is_reg;
- end
-
- default:
- undefined = 1;
- endcase
-
- `GROUP_LDST_MULT: begin
- ldst_ctrl = ldst_multiple;
- ldst_addr = ldst_multiple;
- snd_ctrl.imm = 12'd4;
-
- restore_spsr = ldst_mult_restore_spsr;
- end
-
- `GROUP_CP: begin
- coproc = 1;
- writeback = coproc_writeback;
- update_flags = coproc_update_flags;
-
- data_ctrl.op = `ALU_MOV;
- data_ctrl.rn = coproc_rd;
- data_ctrl.rd = coproc_rd;
- data_ctrl.uses_rn = coproc_ctrl.load;
- end
-
- `INSN_MRS: begin
- snd_ctrl.is_imm = 0;
- snd_ctrl.r = mrs_rd;
-
- writeback = 1;
- conditional = 1;
- end
-
- `GROUP_MSR: begin
- snd_is_imm = msr_is_imm;
- snd_ror_if_imm = 1;
- snd_shift_by_reg_if_reg = 0;
-
- snd_ctrl = snd;
- conditional = 1;
- end
-
- /*`GROUP_SWP: ;
- `INSN_SWI: ;*/
-
- default:
- undefined = 1;
- endcase
-
- unique casez(insn `FIELD_OP)
- `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT: begin
- ldst = 1;
- data_ctrl = data_ldst;
- writeback = ldst_ctrl.writeback || ldst_ctrl.load;
- end
-
- default: ;
- endcase
-
- if(undefined) begin
- execute = 0;
-
- mul = 1'bx;
- ldst = 1'bx;
- branch = 1'bx;
- coproc = 1'bx;
- writeback = 1'bx;
- conditional = 1'bx;
- update_flags = 1'bx;
-
- snd_ctrl = {($bits(snd_ctrl)){1'bx}};
- data_ctrl = {($bits(data_ctrl)){1'bx}};
- ldst_ctrl = {($bits(ldst_ctrl)){1'bx}};
- end
- end
-
endmodule
diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv
new file mode 100644
index 0000000..fcbe62c
--- /dev/null
+++ b/rtl/core/decode/mux.sv
@@ -0,0 +1,239 @@
+`include "core/decode/isa.sv"
+`include "core/uarch.sv"
+
+module core_decode_mux
+(
+ input word insn,
+
+ input logic cond_undefined,
+ cond_execute,
+ explicit_cond,
+
+ input logic branch_link,
+
+ input snd_decode snd,
+ input logic snd_undefined,
+
+ input data_decode data,
+ input logic data_writeback,
+ data_update_flags,
+ data_restore_spsr,
+ data_is_imm,
+ data_shift_by_reg_if_reg,
+
+ input ldst_decode ldst_single,
+ ldst_misc,
+ ldst_multiple,
+ input logic ldst_single_is_imm,
+ ldst_misc_off_is_reg,
+ input reg_num ldst_misc_off_reg,
+ input logic[7:0] ldst_misc_off_imm,
+ input logic ldst_mult_restore_spsr,
+ input data_decode data_ldst,
+
+ input logic mul_update_flags,
+ input reg_num mul_rd,
+ mul_rs,
+ mul_rm,
+
+ input coproc_decode coproc_ctrl,
+ input logic coproc_writeback,
+ coproc_update_flags,
+ input reg_num coproc_rd,
+
+ input logic msr_spsr,
+ msr_is_imm,
+ mrs_spsr,
+ input reg_num mrs_rd,
+ input msr_mask msr_fields,
+
+ output snd_decode snd_ctrl,
+ output data_decode data_ctrl,
+ output ldst_decode ldst_ctrl,
+ ldst_addr,
+ output logic execute,
+ undefined,
+ conditional,
+ writeback,
+ update_flags,
+ branch,
+ ldst,
+ mul,
+ coproc,
+ spsr,
+ psr_write,
+ restore_spsr,
+ snd_is_imm,
+ snd_ror_if_imm,
+ snd_shift_by_reg_if_reg
+);
+
+ always_comb begin
+ mul = 0;
+ ldst = 0;
+ branch = 0;
+ coproc = 0;
+ execute = cond_execute;
+ undefined = cond_undefined;
+ writeback = 0;
+ conditional = explicit_cond;
+
+ spsr = 0;
+ psr_write = 0;
+ update_flags = 0;
+
+ data_ctrl = {($bits(data_ctrl)){1'bx}};
+ data_ctrl.uses_rn = 1;
+
+ snd_ctrl = {$bits(snd_ctrl){1'bx}};
+ snd_ctrl.shr = 0;
+ snd_ctrl.ror = 0;
+ snd_ctrl.is_imm = 1;
+ snd_ctrl.shift_imm = {$bits(snd_ctrl.shift_imm){1'b0}};
+ snd_ctrl.shift_by_reg = 0;
+
+ snd_is_imm = 1'bx;
+ snd_ror_if_imm = 1'bx;
+ snd_shift_by_reg_if_reg = 1'bx;
+
+ ldst_addr = {($bits(ldst_addr)){1'bx}};
+ ldst_ctrl = {($bits(ldst_ctrl)){1'bx}};
+
+ // El orden de los casos es importante, NO CAMBIAR
+ priority casez(insn `FIELD_OP)
+ `GROUP_B: begin
+ branch = 1;
+ if(branch_link) begin
+ data_ctrl.op = `ALU_SUB;
+ data_ctrl.rd = `R14;
+ data_ctrl.rn = `R15;
+ snd_ctrl.imm = 12'd4;
+ writeback = 1;
+ end
+ end
+
+ `GROUP_MUL: begin
+ mul = 1;
+
+ data_ctrl.rd = mul_rd;
+ data_ctrl.rn = mul_rs;
+
+ snd_ctrl.is_imm = 0;
+ snd_ctrl.r = mul_rm;
+
+ writeback = 1;
+ update_flags = mul_update_flags;
+ end
+
+ `GROUP_ALU: begin
+ snd_is_imm = data_is_imm;
+ snd_ror_if_imm = 1;
+ snd_shift_by_reg_if_reg = data_shift_by_reg_if_reg;
+
+ snd_ctrl = snd;
+ data_ctrl = data;
+
+ writeback = data_writeback;
+ update_flags = data_update_flags;
+ restore_spsr = data_restore_spsr;
+ undefined = undefined | snd_undefined;
+ end
+
+ `GROUP_LDST_SINGLE_IMM, `GROUP_LDST_SINGLE_REG: begin
+ snd_is_imm = ldst_single_is_imm;
+ snd_ror_if_imm = 0;
+ snd_shift_by_reg_if_reg = 0;
+
+ snd_ctrl = snd;
+ ldst_ctrl = ldst_single;
+ ldst_addr = ldst_single;
+
+ undefined = undefined | snd_undefined;
+ end
+
+ `GROUP_LDST_MISC_IMM, `GROUP_LDST_MISC_REG:
+ priority casez(insn `FIELD_OP)
+ `INSN_LDRB, `INSN_LDRSB, `INSN_LDRSH, `INSN_STRH: begin
+ ldst_ctrl = ldst_misc;
+ ldst_addr = ldst_misc;
+
+ snd_ctrl.r = ldst_misc_off_reg;
+ snd_ctrl.imm = {4'b0, ldst_misc_off_imm};
+ snd_ctrl.is_imm = !ldst_misc_off_is_reg;
+ end
+
+ default:
+ undefined = 1;
+ endcase
+
+ `GROUP_LDST_MULT: begin
+ ldst_ctrl = ldst_multiple;
+ ldst_addr = ldst_multiple;
+ snd_ctrl.imm = 12'd4;
+
+ restore_spsr = ldst_mult_restore_spsr;
+ end
+
+ `GROUP_CP: begin
+ coproc = 1;
+ writeback = coproc_writeback;
+ update_flags = coproc_update_flags;
+
+ data_ctrl.op = `ALU_MOV;
+ data_ctrl.rn = coproc_rd;
+ data_ctrl.rd = coproc_rd;
+ data_ctrl.uses_rn = coproc_ctrl.load;
+ end
+
+ `INSN_MRS: begin
+ snd_ctrl.is_imm = 0;
+ snd_ctrl.r = mrs_rd;
+
+ writeback = 1;
+ conditional = 1;
+ end
+
+ `GROUP_MSR: begin
+ snd_is_imm = msr_is_imm;
+ snd_ror_if_imm = 1;
+ snd_shift_by_reg_if_reg = 0;
+
+ snd_ctrl = snd;
+ conditional = 1;
+ end
+
+ /*`GROUP_SWP: ;
+ `INSN_SWI: ;*/
+
+ default:
+ undefined = 1;
+ endcase
+
+ unique casez(insn `FIELD_OP)
+ `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT: begin
+ ldst = 1;
+ data_ctrl = data_ldst;
+ writeback = ldst_ctrl.writeback || ldst_ctrl.load;
+ end
+
+ default: ;
+ endcase
+
+ if(undefined) begin
+ execute = 0;
+
+ mul = 1'bx;
+ ldst = 1'bx;
+ branch = 1'bx;
+ coproc = 1'bx;
+ writeback = 1'bx;
+ conditional = 1'bx;
+ update_flags = 1'bx;
+
+ snd_ctrl = {($bits(snd_ctrl)){1'bx}};
+ data_ctrl = {($bits(data_ctrl)){1'bx}};
+ ldst_ctrl = {($bits(ldst_ctrl)){1'bx}};
+ end
+ end
+
+endmodule