summaryrefslogtreecommitdiff
path: root/rtl/core
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/core')
-rw-r--r--rtl/core/arm810.sv15
-rw-r--r--rtl/core/control/control.sv126
-rw-r--r--rtl/core/control/cycles.sv56
-rw-r--r--rtl/core/control/mux.sv50
-rw-r--r--rtl/core/control/stall.sv44
-rw-r--r--rtl/core/decode/data.sv6
-rw-r--r--rtl/core/decode/decode.sv40
-rw-r--r--rtl/core/decode/isa.sv4
-rw-r--r--rtl/core/decode/snd.sv18
-rw-r--r--rtl/core/shifter.sv2
-rw-r--r--rtl/core/uarch.sv28
11 files changed, 247 insertions, 142 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index 6d4880f..266832f 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -29,23 +29,16 @@ module arm810
.*
);
- ptr dec_branch_offset;
+ datapath_decode dec;
+ branch_decode dec_branch;
snd_decode dec_snd;
data_decode dec_data;
ldst_decode dec_ldst;
- logic dec_execute, dec_conditional, dec_undefined, dec_writeback,
- dec_branch, dec_update_flags, dec_uses_rn;
core_decode decode
(
- .execute(dec_execute),
- .conditional(dec_conditional),
- .undefined(dec_undefined),
- .writeback(dec_writeback),
- .uses_rn(dec_uses_rn),
- .branch(dec_branch),
- .update_flags(dec_update_flags),
- .branch_offset(dec_branch_offset),
+ .ctrl(dec),
+ .branch_ctrl(dec_branch),
.snd_ctrl(dec_snd),
.data_ctrl(dec_data),
.ldst_ctrl(dec_ldst),
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index 95d3bb9..059cb2d 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -3,16 +3,10 @@
module core_control
(
input logic clk,
- dec_execute,
- dec_undefined,
- dec_conditional,
- dec_uses_rn,
- dec_branch,
- dec_writeback,
- dec_update_flags,
- input ptr dec_branch_offset,
- input snd_decode dec_snd,
+ input datapath_decode dec,
+ input branch_decode dec_branch,
input data_decode dec_data,
+ input snd_decode dec_snd,
input ldst_decode dec_ldst,
input ptr fetch_insn_pc,
input psr_flags flags,
@@ -49,17 +43,7 @@ module core_control
mem_write
);
- enum
- {
- ISSUE,
- RD_INDIRECT_SHIFT,
- WITH_SHIFT,
- TRANSFER,
- BASE_WRITEBACK,
- EXCEPTION
- } cycle, next_cycle;
-
- logic bubble, next_bubble, final_writeback, final_update_flags,
+ logic final_writeback, final_update_flags,
ldst, ldst_pre, ldst_increment, ldst_writeback, pop_valid,
data_snd_is_imm, data_snd_shift_by_reg, trivial_shift,
undefined, exception, high_vectors;
@@ -72,7 +56,6 @@ module core_control
reg_list mem_regs, next_regs_upper, next_regs_lower;
ptr pc /*verilator public*/, next_pc_visible;
- assign stall = next_cycle != ISSUE || next_bubble;
assign reg_mode = `MODE_SVC; //TODO
assign trivial_shift = shifter_shift == 0;
assign mem_data_wr = rd_value_b;
@@ -82,10 +65,19 @@ module core_control
assign vector = {{16{high_vectors}}, 11'b0, vector_offset, 2'b00};
assign next_pc_visible = fetch_insn_pc + 2;
- assign next_bubble =
- ((dec_update_flags || dec_conditional) && (final_update_flags || update_flags))
- || (final_writeback && ((dec_uses_rn && (final_rd == dec_data.rn || dec_data.rn == `R15))
- || final_rd == dec_snd.r || dec_snd.r == `R15));
+ ctrl_cycle cycle, next_cycle;
+
+ core_control_cycles cycles
+ (
+ .*
+ );
+
+ logic bubble, next_bubble;
+
+ core_control_stall ctrl_stall
+ (
+ .*
+ );
core_control_ldst_pop ldst_pop
(
@@ -97,67 +89,15 @@ module core_control
.pop_lower(popped_lower)
);
- 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
-
- next_cycle = ISSUE;
-
- unique case(cycle)
- ISSUE:
- if(exception)
- next_cycle = EXCEPTION;
- else if(data_snd_shift_by_reg)
- next_cycle = RD_INDIRECT_SHIFT;
- else if(~trivial_shift)
- next_cycle = WITH_SHIFT;
-
- RD_INDIRECT_SHIFT:
- if(~trivial_shift)
- next_cycle = WITH_SHIFT;
-
- TRANSFER:
- if(!mem_ready || pop_valid)
- next_cycle = TRANSFER;
- else if(ldst_writeback)
- next_cycle = BASE_WRITEBACK;
-
- default: ;
- endcase
-
- if(bubble)
- next_cycle = ISSUE;
- else if(next_cycle == ISSUE && ldst)
- next_cycle = TRANSFER;
-
- 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
+ core_control_mux mux
+ (
+ .*
+ );
+ always_comb
vector_offset = 3'b001; //TODO
- end
always_ff @(posedge clk) begin
- cycle <= next_cycle;
- bubble <= 0;
branch <= 0;
writeback <= 0;
update_flags <= 0;
@@ -174,11 +114,9 @@ module core_control
final_writeback <= 0;
final_update_flags <= 0;
- bubble <= next_bubble;
-
- if(dec_execute & ~next_bubble) begin
- branch <= dec_branch;
- branch_target <= next_pc_visible + dec_branch_offset;
+ if(dec.execute & ~next_bubble) begin
+ branch <= dec_branch.branch;
+ branch_target <= next_pc_visible + dec_branch.offset;
alu <= dec_data.op;
ra <= dec_data.rn;
@@ -208,13 +146,13 @@ module core_control
mem_write <= !dec_ldst.load;
final_rd <= dec_data.rd;
- final_writeback <= dec_writeback;
- final_update_flags <= dec_update_flags;
+ final_writeback <= dec.writeback;
+ final_update_flags <= dec.update_flags;
end
update_flags <= final_update_flags;
writeback <= final_writeback;
- undefined <= dec_undefined;
+ undefined <= dec.undefined;
rd <= final_rd;
pc <= fetch_insn_pc;
@@ -238,9 +176,10 @@ module core_control
mem_offset <= alu_b;
end
+ writeback <= mem_ready && !mem_write;
if(mem_ready) begin
+ rd <= final_rd;
wr_value <= mem_data_rd;
- writeback <= !mem_write;
end
if(cycle != TRANSFER || mem_ready) begin
@@ -249,8 +188,8 @@ module core_control
saved_base <= q_alu;
if(pop_valid) begin
- rd <= popped;
rb <= popped;
+ final_rd <= popped;
end else
rb <= final_rd; // Viene de dec_ldst.rd
end
@@ -286,9 +225,6 @@ module core_control
end
initial begin
- cycle = ISSUE;
- bubble = 0;
-
pc = 0;
pc_visible = 2;
diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv
new file mode 100644
index 0000000..f804e93
--- /dev/null
+++ b/rtl/core/control/cycles.sv
@@ -0,0 +1,56 @@
+`include "core/uarch.sv"
+
+module core_control_cycles
+(
+ input logic clk,
+ ldst,
+ bubble,
+ exception,
+ mem_ready,
+ pop_valid,
+ trivial_shift,
+ ldst_writeback,
+ data_snd_shift_by_reg,
+
+ output ctrl_cycle cycle,
+ next_cycle
+);
+
+ always_comb begin
+ next_cycle = ISSUE;
+
+ unique case(cycle)
+ ISSUE:
+ if(exception)
+ next_cycle = EXCEPTION;
+ else if(data_snd_shift_by_reg)
+ next_cycle = RD_INDIRECT_SHIFT;
+ else if(!trivial_shift)
+ next_cycle = WITH_SHIFT;
+
+ RD_INDIRECT_SHIFT:
+ if(!trivial_shift)
+ next_cycle = WITH_SHIFT;
+
+ TRANSFER:
+ if(!mem_ready || pop_valid)
+ next_cycle = TRANSFER;
+ else if(ldst_writeback)
+ next_cycle = BASE_WRITEBACK;
+
+ default: ;
+ endcase
+
+ if(bubble)
+ next_cycle = ISSUE;
+ else if(next_cycle == ISSUE && ldst)
+ next_cycle = TRANSFER;
+ end
+
+ always_ff @(posedge clk)
+ cycle <= next_cycle;
+
+ initial
+ cycle = ISSUE;
+
+endmodule
diff --git a/rtl/core/control/mux.sv b/rtl/core/control/mux.sv
new file mode 100644
index 0000000..58d2197
--- /dev/null
+++ b/rtl/core/control/mux.sv
@@ -0,0 +1,50 @@
+`include "core/uarch.sv"
+
+module core_control_mux
+(
+ input logic clk,
+
+ input word rd_value_a,
+ rd_value_b,
+
+ input ctrl_cycle cycle,
+ input logic data_snd_is_imm,
+ input logic[5:0] data_shift_imm,
+ input logic[11:0] data_imm,
+ input ptr pc,
+ input word saved_base,
+ mem_offset,
+
+ output word alu_a,
+ alu_b,
+ output logic[7:0] shifter_shift
+);
+
+ 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
+
+endmodule
diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv
new file mode 100644
index 0000000..4dc56e4
--- /dev/null
+++ b/rtl/core/control/stall.sv
@@ -0,0 +1,44 @@
+`include "core/uarch.sv"
+
+module core_control_stall
+(
+ input logic clk,
+
+ input datapath_decode dec,
+ input data_decode dec_data,
+ input snd_decode dec_snd,
+
+ input ctrl_cycle next_cycle,
+ input logic final_update_flags,
+ update_flags,
+ final_writeback,
+ writeback,
+ input reg_num final_rd,
+
+ output logic stall,
+ bubble,
+ next_bubble
+);
+
+ logic pc_writeback_hazard, flags_hazard, data_hazard, rn_hazard,
+ snd_hazard, flags_dependency, updating_flags;
+
+ assign stall = next_cycle != ISSUE || next_bubble;
+ assign next_bubble = pc_writeback_hazard || flags_hazard || data_hazard;
+
+ assign pc_writeback_hazard = final_writeback && final_rd == `R15;
+ assign flags_hazard = flags_dependency && updating_flags;
+ assign data_hazard = final_writeback && (rn_hazard || snd_hazard);
+ assign rn_hazard = dec_data.uses_rn && (final_rd == dec_data.rn || dec_data.rn == `R15);
+ assign snd_hazard = !dec_snd.is_imm && (dec_snd.r == final_rd || dec_snd.r == `R15);
+
+ assign flags_dependency = dec.update_flags || dec.conditional;
+ assign updating_flags = final_update_flags || update_flags;
+
+ always_ff @(posedge clk)
+ bubble <= next_cycle == ISSUE ? next_bubble : 0;
+
+ initial
+ bubble = 0;
+
+endmodule
diff --git a/rtl/core/decode/data.sv b/rtl/core/decode/data.sv
index 103fb14..1bd7ef9 100644
--- a/rtl/core/decode/data.sv
+++ b/rtl/core/decode/data.sv
@@ -10,16 +10,18 @@ module core_decode_data
snd_shift_by_reg_if_reg,
writeback,
update_flags,
- restore_spsr,
- uses_rn
+ restore_spsr
);
alu_op op;
reg_num rn, rd;
+ logic uses_rn;
assign decode.op = op;
assign decode.rn = rn;
assign decode.rd = rd;
+ assign decode.uses_rn = uses_rn;
+
assign rn = insn `FIELD_DATA_RN;
assign rd = insn `FIELD_DATA_RD;
assign op = insn `FIELD_DATA_OPCODE;
diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv
index 9367e6d..2740b70 100644
--- a/rtl/core/decode/decode.sv
+++ b/rtl/core/decode/decode.sv
@@ -3,22 +3,25 @@
module core_decode
(
- input word insn,
- input psr_flags flags,
-
- output logic execute,
- conditional,
- undefined,
- writeback,
- update_flags,
- uses_rn,
- branch,
- output ptr branch_offset,
- output snd_decode snd_ctrl,
- output data_decode data_ctrl,
- output ldst_decode ldst_ctrl
+ input word insn,
+ input psr_flags flags,
+
+ output datapath_decode ctrl,
+ output branch_decode branch_ctrl,
+ output snd_decode snd_ctrl,
+ output data_decode data_ctrl,
+ output ldst_decode ldst_ctrl
);
+ logic execute, undefined, conditional, writeback, update_flags, branch;
+
+ assign ctrl.execute = execute;
+ assign ctrl.undefined = undefined;
+ assign ctrl.conditional = conditional;
+ assign ctrl.writeback = writeback;
+ assign ctrl.update_flags = update_flags;
+ assign branch_ctrl.branch = branch;
+
//TODO
logic restore_spsr;
@@ -50,13 +53,13 @@ module core_decode
core_decode_branch group_branch
(
.link(branch_link),
- .offset(branch_offset),
+ .offset(branch_ctrl.offset),
.*
);
data_decode data;
logic data_writeback, data_update_flags, data_restore_spsr,
- data_is_imm, data_shift_by_reg_if_reg, data_uses_rn;
+ data_is_imm, data_shift_by_reg_if_reg;
core_decode_data group_data
(
@@ -66,7 +69,6 @@ module core_decode
.restore_spsr(data_restore_spsr),
.snd_is_imm(data_is_imm),
.snd_shift_by_reg_if_reg(data_shift_by_reg_if_reg),
- .uses_rn(data_uses_rn),
.*
);
@@ -117,11 +119,11 @@ module core_decode
branch = 0;
writeback = 0;
update_flags = 0;
- uses_rn = 1;
execute = cond_execute;
undefined = cond_undefined;
data_ctrl = {($bits(data_ctrl)){1'bx}};
+ data_ctrl.uses_rn = 1;
snd_ctrl = {$bits(snd_ctrl){1'bx}};
snd_ctrl.shr = 0;
@@ -152,7 +154,6 @@ module core_decode
end
`GROUP_ALU: begin
- uses_rn = data_uses_rn;
snd_is_imm = data_is_imm;
snd_ror_if_imm = 1;
snd_shift_by_reg_if_reg = data_shift_by_reg_if_reg;
@@ -227,7 +228,6 @@ module core_decode
execute = 0;
branch = 1'bx;
- uses_rn = 1'bx;
writeback = 1'bx;
conditional = 1'bx;
update_flags = 1'bx;
diff --git a/rtl/core/decode/isa.sv b/rtl/core/decode/isa.sv
index baaf371..98d338e 100644
--- a/rtl/core/decode/isa.sv
+++ b/rtl/core/decode/isa.sv
@@ -66,7 +66,9 @@
`define INSN_BIC 28'b00_?_1110_?_????_????_????????????
`define INSN_MVN 28'b00_?_1111_?_0000_????_????????????
-`define GROUP_ALU 28'b00_?_????_?_????_????_????????????
+`define GROUP_ALU \
+ `INSN_AND, `INSN_EOR, `INSN_SUB, `INSN_RSB, `INSN_ADD, `INSN_ADC, `INSN_SBC, `INSN_RSC, \
+ `INSN_TST, `INSN_TEQ, `INSN_CMP, `INSN_CMN, `INSN_ORR, `INSN_MOV, `INSN_BIC, `INSN_MVN
`define FIELD_DATA_IMM [25]
`define FIELD_DATA_OPCODE [24:21]
diff --git a/rtl/core/decode/snd.sv b/rtl/core/decode/snd.sv
index 78c5424..264982e 100644
--- a/rtl/core/decode/snd.sv
+++ b/rtl/core/decode/snd.sv
@@ -41,23 +41,21 @@ module core_decode_snd
ror = is_imm;
shr = ~is_imm;
put_carry = 0;
- sign_extend = 1'bx;
+ sign_extend = 0;
- if(is_imm && !ror_if_imm)
- shift_imm = 6'b0;
- else if(is_imm && !ror_if_imm)
- shift_imm = {1'b0, insn `FIELD_SND_ROR8, 1'b0};
+ if(is_imm)
+ shift_imm = ror_if_imm ? {1'b0, insn `FIELD_SND_ROR8, 1'b0} : 6'b0;
else begin
shift_imm = {1'b0, insn `FIELD_SND_SHIFTIMM};
case(shift_op)
`SHIFT_LSL: shr = 0;
- `SHIFT_LSR: sign_extend = 0;
+ `SHIFT_LSR: ;
`SHIFT_ASR: sign_extend = 1;
- `SHIFT_ROR: ;
+ `SHIFT_ROR: ror = 1;
endcase
- if(~shift_by_reg & (shift_imm == 0))
+ if(!shift_by_reg && shift_imm == 0)
case(shift_op)
`SHIFT_LSL: ;
@@ -66,13 +64,11 @@ module core_decode_snd
`SHIFT_ROR: begin
// RRX
+ ror = 0;
shift_imm = 6'd1;
put_carry = 1;
- sign_extend = 0;
end
endcase
- else if(shift_op == `SHIFT_ROR)
- ror = 1;
end
end
diff --git a/rtl/core/shifter.sv b/rtl/core/shifter.sv
index 994e76c..2b5739d 100644
--- a/rtl/core/shifter.sv
+++ b/rtl/core/shifter.sv
@@ -20,7 +20,7 @@ module core_shifter
assign sign_mask = {(W + 1){ctrl.sign_extend & base[W - 1]}};
assign {c_shl, q_shl} = {c_in, base} << shift;
- assign {q_shr, c_shr} = {base, c_in} >> shift | ~(sign_mask >> shift);
+ assign {q_shr, c_shr} = {base, c_in} >> shift | (sign_mask & ~(sign_mask >> shift));
logic ror_cycle;
logic[LOG - 1:0] ror_shift;
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index 5b4183c..0c46dc7 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -59,13 +59,29 @@ typedef logic[4:0] psr_mode;
typedef struct packed
{
+ logic execute,
+ undefined,
+ conditional,
+ writeback,
+ update_flags;
+} datapath_decode;
+
+typedef struct packed
+{
alu_op op;
reg_num rn,
rd;
+ logic uses_rn;
} data_decode;
typedef struct packed
{
+ logic branch;
+ ptr offset;
+} branch_decode;
+
+typedef struct packed
+{
reg_num r,
r_shift;
logic shift_by_reg,
@@ -78,7 +94,7 @@ typedef struct packed
logic[5:0] shift_imm;
} snd_decode;
-typedef enum logic[1:0]
+typedef enum
{
LDST_WORD,
LDST_BYTE,
@@ -107,6 +123,16 @@ typedef struct packed
reg_list regs;
} ldst_decode;
+typedef enum
+{
+ ISSUE,
+ RD_INDIRECT_SHIFT,
+ WITH_SHIFT,
+ TRANSFER,
+ BASE_WRITEBACK,
+ EXCEPTION
+} ctrl_cycle;
+
typedef struct packed
{
logic shr,