summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-11-13 05:22:23 -0600
committerAlejandro Soto <alejandro@34project.org>2022-11-13 05:54:44 -0600
commitd463acba5f9589085afb3dcc4058d82908ff90f2 (patch)
treee4ba47f2f9daa8e25b5c244f7af934ff18b54cbc /rtl
parent6cb000adf57d7af2ec4aac8fd93d12f09cc63556 (diff)
Convert core state machines to Quartus-inferring RTL
Diffstat (limited to '')
-rw-r--r--rtl/bus_master.sv3
-rw-r--r--rtl/core/control/branch.sv2
-rw-r--r--rtl/core/control/coproc.sv2
-rw-r--r--rtl/core/control/cycles.sv76
-rw-r--r--rtl/core/control/data.sv107
-rw-r--r--rtl/core/control/issue.sv4
-rw-r--r--rtl/core/control/ldst/ldst.sv19
-rw-r--r--rtl/core/control/mul.sv31
-rw-r--r--rtl/core/control/select.sv29
-rw-r--r--rtl/core/control/stall.sv4
-rw-r--r--rtl/core/control/writeback.sv157
-rw-r--r--rtl/core/mmu/mmu.sv2
-rw-r--r--rtl/core/uarch.sv23
13 files changed, 222 insertions, 237 deletions
diff --git a/rtl/bus_master.sv b/rtl/bus_master.sv
index c61a208..7775e42 100644
--- a/rtl/bus_master.sv
+++ b/rtl/bus_master.sv
@@ -23,7 +23,8 @@ module bus_master
input logic avl_irq
);
- enum {
+ enum int unsigned
+ {
IDLE,
WAIT
} state;
diff --git a/rtl/core/control/branch.sv b/rtl/core/control/branch.sv
index 96e6e65..0298b95 100644
--- a/rtl/core/control/branch.sv
+++ b/rtl/core/control/branch.sv
@@ -21,7 +21,7 @@ module core_control_branch
branch_target <= {$bits(branch_target){1'b0}};
end else begin
branch <= 0;
- if(next_cycle == ISSUE && issue) begin
+ if(next_cycle.issue && issue) begin
branch <= dec.ctrl.branch;
branch_target <= next_pc_visible + dec.branch.offset;
end
diff --git a/rtl/core/control/coproc.sv b/rtl/core/control/coproc.sv
index a457b0f..76f0a53 100644
--- a/rtl/core/control/coproc.sv
+++ b/rtl/core/control/coproc.sv
@@ -16,7 +16,7 @@ module core_control_coproc
always_ff @(posedge clk or negedge rst_n)
if(!rst_n)
coproc <= 0;
- else if(next_cycle == ISSUE && issue)
+ else if(next_cycle.issue && issue)
coproc <= dec.ctrl.coproc;
endmodule
diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv
index 0c5d94c..5904a49 100644
--- a/rtl/core/control/cycles.sv
+++ b/rtl/core/control/cycles.sv
@@ -22,50 +22,92 @@ module core_control_cycles
next_cycle
);
+ /* qts-qii51007-recommended-hdl.pdf, p. 66
+ * In Quartus II integrated synthesis, the enumerated type that defines the states for the
+ * state machine must be of an unsigned integer type as in Example 13–52. If you do not
+ * specify the enumerated type as int unsigned, a signed int type is used by default. In
+ * this case, the Quartus II integrated synthesis synthesizes the design, but does not infer
+ * or optimize the logic as a state machine.
+ */
+ enum int unsigned
+ {
+ ISSUE,
+ RD_INDIRECT_SHIFT,
+ WITH_SHIFT,
+ TRANSFER,
+ BASE_WRITEBACK,
+ EXCEPTION,
+ MUL,
+ MUL_ACC_LD,
+ MUL_HI_WB
+ } state, next_state;
+
+ // TODO: debe estar escrito de tal forma que Quartus infiera una FSM
+
+ assign cycle.issue = state == ISSUE;
+ assign cycle.rd_indirect_shift = state == RD_INDIRECT_SHIFT;
+ assign cycle.with_shift = state == WITH_SHIFT;
+ assign cycle.transfer = state == TRANSFER;
+ assign cycle.base_writeback = state == BASE_WRITEBACK;
+ assign cycle.exception = state == EXCEPTION;
+ assign cycle.mul = state == MUL;
+ assign cycle.mul_acc_ld = state == MUL_ACC_LD;
+ assign cycle.mul_hi_wb = state == MUL_HI_WB;
+
+ assign next_cycle.issue = next_state == ISSUE;
+ assign next_cycle.rd_indirect_shift = next_state == RD_INDIRECT_SHIFT;
+ assign next_cycle.with_shift = next_state == WITH_SHIFT;
+ assign next_cycle.transfer = next_state == TRANSFER;
+ assign next_cycle.base_writeback = next_state == BASE_WRITEBACK;
+ assign next_cycle.exception = next_state == EXCEPTION;
+ assign next_cycle.mul = next_state == MUL;
+ assign next_cycle.mul_acc_ld = next_state == MUL_ACC_LD;
+ assign next_cycle.mul_hi_wb = next_state == MUL_HI_WB;
+
always_comb begin
- next_cycle = ISSUE;
+ next_state = ISSUE;
- unique case(cycle)
+ unique case(state)
ISSUE:
if(exception)
- next_cycle = EXCEPTION;
+ next_state = EXCEPTION;
else if(halt)
- next_cycle = ISSUE;
+ next_state = ISSUE;
else if(mul)
- next_cycle = mul_add ? MUL_ACC_LD : MUL;
+ next_state = mul_add ? MUL_ACC_LD : MUL;
else if(data_snd_shift_by_reg)
- next_cycle = RD_INDIRECT_SHIFT;
+ next_state = RD_INDIRECT_SHIFT;
else if(!trivial_shift)
- next_cycle = WITH_SHIFT;
+ next_state = WITH_SHIFT;
RD_INDIRECT_SHIFT:
if(!trivial_shift)
- next_cycle = WITH_SHIFT;
+ next_state = WITH_SHIFT;
TRANSFER:
if(!mem_ready || pop_valid)
- next_cycle = TRANSFER;
+ next_state = TRANSFER;
else if(ldst_writeback)
- next_cycle = BASE_WRITEBACK;
+ next_state = BASE_WRITEBACK;
MUL:
if(!mul_ready)
- next_cycle = MUL;
+ next_state = MUL;
else if(mul_long)
- next_cycle = MUL_HI_WB;
+ next_state = MUL_HI_WB;
MUL_ACC_LD:
- next_cycle = MUL;
+ next_state = MUL;
endcase
if(bubble)
- next_cycle = ISSUE;
- else if(next_cycle == ISSUE && ldst) begin
- next_cycle = TRANSFER;
+ next_state = ISSUE;
+ else if(next_state == ISSUE && ldst) begin
+ next_state = TRANSFER;
end
end
always_ff @(posedge clk or negedge rst_n)
- cycle <= !rst_n ? ISSUE : next_cycle;
+ state <= !rst_n ? ISSUE : next_state;
endmodule
diff --git a/rtl/core/control/data.sv b/rtl/core/control/data.sv
index 0824eac..049cf0e 100644
--- a/rtl/core/control/data.sv
+++ b/rtl/core/control/data.sv
@@ -37,30 +37,26 @@ module core_control_data
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
+ if(cycle.rd_indirect_shift)
+ shifter_shift = rd_value_b[7:0];
+ else
+ shifter_shift = {2'b00, data_shift_imm};
+
+ if(cycle.transfer)
+ alu_a = saved_base;
+ else if(cycle.exception)
+ alu_a = {pc, 2'b00};
+ else
+ alu_a = rd_value_a;
+
+ if(cycle.rd_indirect_shift || cycle.with_shift)
+ alu_b = saved_base;
+ else if(cycle.transfer)
+ alu_b = mem_offset;
+ else if(data_snd_is_imm)
+ alu_b = {{20{1'b0}}, data_imm};
+ else
+ alu_b = rd_value_b;
end
always_ff @(posedge clk or negedge rst_n)
@@ -73,41 +69,32 @@ module core_control_data
data_shift_imm <= {$bits(data_shift_imm){1'b0}};
data_snd_is_imm <= 0;
data_snd_shift_by_reg <= 0;
- end else unique case(next_cycle)
- ISSUE: begin
- alu <= dec.data.op;
- c_in <= flags.c;
-
- data_imm <= dec.snd.imm;
- data_shift_imm <= dec.snd.shift_imm;
- data_snd_is_imm <= dec.snd.is_imm;
- data_snd_shift_by_reg <= dec.snd.shift_by_reg;
-
- 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
+ end else if(next_cycle.issue) begin
+ alu <= dec.data.op;
+ c_in <= flags.c;
+
+ data_imm <= dec.snd.imm;
+ data_shift_imm <= dec.snd.shift_imm;
+ data_snd_is_imm <= dec.snd.is_imm;
+ data_snd_shift_by_reg <= dec.snd.shift_by_reg;
+
+ 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 else if(next_cycle.rd_indirect_shift) begin
+ saved_base <= rd_value_b;
+ data_snd_shift_by_reg <= 0;
+ end else if(next_cycle.with_shift) begin
+ c_in <= c_shifter;
+ saved_base <= q_shifter;
+ end else if(next_cycle.transfer) begin
+ if(!cycle.transfer || mem_ready)
+ saved_base <= q_alu;
+ end else if(next_cycle.exception) begin
+ alu <= `ALU_ADD;
+ data_imm <= 12'd4;
+ data_snd_is_imm <= 1;
+ end
endmodule
diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv
index b2ee6e5..c1c932e 100644
--- a/rtl/core/control/issue.sv
+++ b/rtl/core/control/issue.sv
@@ -23,7 +23,7 @@ module core_control_issue
next_pc_visible
);
- assign issue = next_cycle == ISSUE && dec.ctrl.execute && !next_bubble && !halt;
+ assign issue = next_cycle.issue && dec.ctrl.execute && !next_bubble && !halt;
assign next_pc_visible = insn_pc + 2;
always_ff @(posedge clk or negedge rst_n)
@@ -31,7 +31,7 @@ module core_control_issue
pc <= 0;
undefined <= 0;
pc_visible <= 2;
- end else if(next_cycle == ISSUE) begin
+ end else if(next_cycle.issue) begin
undefined <= dec.ctrl.undefined;
`ifdef VERILATOR
diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv
index ef91775..cc52864 100644
--- a/rtl/core/control/ldst/ldst.sv
+++ b/rtl/core/control/ldst/ldst.sv
@@ -56,8 +56,10 @@ module core_control_ldst
mem_write <= 0;
mem_start <= 0;
mem_offset <= 0;
- end else unique case(next_cycle)
- ISSUE: begin
+ end else begin
+ mem_start <= 0;
+
+ if(next_cycle.issue) begin
// TODO: dec.ldst.unprivileged/user_regs
// TODO: byte/halfword sizes
if(issue)
@@ -69,21 +71,18 @@ module core_control_ldst
mem_regs <= dec.ldst.regs;
mem_write <= !dec.ldst.load;
- end
-
- TRANSFER: begin
- if(cycle != TRANSFER) begin
+ end else if(next_cycle.transfer) begin
+ if(!cycle.transfer) begin
ldst <= 0;
mem_offset <= alu_b;
end
- if(cycle != TRANSFER || mem_ready) begin
+ 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);
+ mem_start <= !cycle.transfer || (mem_ready && pop_valid);
end
- endcase
-
+ end
endmodule
diff --git a/rtl/core/control/mul.sv b/rtl/core/control/mul.sv
index 9e66053..8352435 100644
--- a/rtl/core/control/mul.sv
+++ b/rtl/core/control/mul.sv
@@ -47,24 +47,19 @@ module core_control_mul
end else begin
mul_start <= 0;
- unique case(next_cycle)
- ISSUE: begin
- mul <= issue && dec.ctrl.mul;
- mul_add <= dec.mul.add;
- mul_long <= dec.mul.long_mul;
- mul_signed <= dec.mul.signed_mul;
- mul_r_add_hi <= dec.mul.r_add_hi;
- mul_r_add_lo <= dec.mul.r_add_lo;
- end
-
- MUL:
- mul_start <= cycle != MUL;
-
- MUL_ACC_LD: begin
- hold_a <= rd_value_a;
- hold_b <= rd_value_b;
- end
- endcase
+ if(next_cycle.issue) begin
+ mul <= issue && dec.ctrl.mul;
+ mul_add <= dec.mul.add;
+ mul_long <= dec.mul.long_mul;
+ mul_signed <= dec.mul.signed_mul;
+ mul_r_add_hi <= dec.mul.r_add_hi;
+ mul_r_add_lo <= dec.mul.r_add_lo;
+ end else if(next_cycle.mul)
+ mul_start <= !cycle.mul;
+ else if(next_cycle.mul_acc_ld) begin
+ hold_a <= rd_value_a;
+ hold_b <= rd_value_b;
+ end
end
//TODO: mul update_flags
diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv
index 80a437f..ee63b42 100644
--- a/rtl/core/control/select.sv
+++ b/rtl/core/control/select.sv
@@ -29,22 +29,17 @@ module core_control_select
ra = last_ra;
rb = last_rb;
- unique case(next_cycle)
- ISSUE: begin
- ra = dec.data.rn;
- rb = dec.snd.r;
- end
-
- TRANSFER:
- if(cycle != TRANSFER || mem_ready)
- // final_rd viene de dec.ldst.rd
- rb = pop_valid ? popped : final_rd;
-
- MUL_ACC_LD: begin
- ra = mul_r_add_hi;
- rb = mul_r_add_lo;
- end
- endcase
+ if(next_cycle.issue) begin
+ ra = dec.data.rn;
+ rb = dec.snd.r;
+ end else if(next_cycle.transfer) begin
+ if(!cycle.transfer || mem_ready)
+ // final_rd viene de dec.ldst.rd
+ rb = pop_valid ? popped : final_rd;
+ end else if(next_cycle.mul_acc_ld) begin
+ ra = mul_r_add_hi;
+ rb = mul_r_add_lo;
+ end
end
always_ff @(posedge clk or negedge rst_n)
@@ -56,7 +51,7 @@ module core_control_select
last_ra <= ra;
last_rb <= rb;
- if(next_cycle == ISSUE)
+ if(next_cycle.issue)
r_shift <= dec.snd.r_shift;
end
diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv
index c2a6ddd..d590325 100644
--- a/rtl/core/control/stall.sv
+++ b/rtl/core/control/stall.sv
@@ -24,7 +24,7 @@ module core_control_stall
logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard,
flags_hazard, flags_dependency, updating_flags;
- assign stall = next_cycle != ISSUE || next_bubble || halt;
+ assign stall = !next_cycle.issue || next_bubble || halt;
assign halted = halt && !next_bubble;
assign next_bubble = pc_rd_hazard || pc_wr_hazard || flags_hazard;
@@ -40,6 +40,6 @@ module core_control_stall
assign flags_dependency = dec.psr.update_flags || dec.ctrl.conditional;
always_ff @(posedge clk or negedge rst_n)
- bubble <= !rst_n ? 0 : next_cycle == ISSUE && next_bubble;
+ bubble <= !rst_n ? 0 : next_cycle.issue && next_bubble;
endmodule
diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv
index 74eb47c..a85956f 100644
--- a/rtl/core/control/writeback.sv
+++ b/rtl/core/control/writeback.sv
@@ -38,67 +38,46 @@ module core_control_writeback
always_comb begin
rd = last_rd;
- unique case(next_cycle)
- TRANSFER:
- if(mem_ready)
- rd = final_rd;
-
- ISSUE, BASE_WRITEBACK:
+ if(next_cycle.transfer) begin
+ if(mem_ready)
rd = final_rd;
-
- EXCEPTION:
- rd = `R15;
-
- MUL_HI_WB:
- rd = mul_r_add_hi;
- endcase
-
- unique case(next_cycle)
- ISSUE:
- writeback = final_writeback;
-
- TRANSFER:
- writeback = mem_ready && !mem_write;
-
- BASE_WRITEBACK:
- writeback = !mem_write;
-
- EXCEPTION, MUL_HI_WB:
- writeback = 1;
-
- default:
- writeback = 0;
- endcase
-
- unique case(cycle)
- TRANSFER:
+ end else if(next_cycle.issue || next_cycle.base_writeback)
+ rd = final_rd;
+ else if(next_cycle.exception)
+ rd = `R15;
+ else if(next_cycle.mul_hi_wb)
+ rd = mul_r_add_hi;
+
+ if(next_cycle.issue)
+ writeback = final_writeback;
+ else if(next_cycle.transfer)
+ writeback = mem_ready && !mem_write;
+ else if(next_cycle.base_writeback)
+ writeback = !mem_write;
+ else if(next_cycle.exception || next_cycle.mul_hi_wb)
+ writeback = 1;
+ else
+ writeback = 0;
+
+ if(cycle.transfer)
+ wr_value = mem_data_rd;
+ else if(cycle.base_writeback)
+ wr_value = saved_base;
+ else if(cycle.mul || cycle.mul_hi_wb)
+ wr_value = mul_q_lo;
+ else
+ // Ruta combinacional larga
+ wr_value = q_alu;
+
+ if(next_cycle.transfer) begin
+ if(mem_ready)
wr_value = mem_data_rd;
-
- BASE_WRITEBACK:
- wr_value = saved_base;
-
- MUL, MUL_HI_WB:
- wr_value = mul_q_lo;
-
- default:
- // Ruta combinacional larga
- wr_value = q_alu;
- endcase
-
- unique case(next_cycle)
- TRANSFER:
- if(mem_ready)
- wr_value = mem_data_rd;
-
- BASE_WRITEBACK:
- wr_value = mem_data_rd;
-
- EXCEPTION:
- wr_value = vector;
-
- MUL_HI_WB:
- wr_value = mul_q_hi;
- endcase
+ end else if(next_cycle.base_writeback)
+ wr_value = mem_data_rd;
+ else if(next_cycle.exception)
+ wr_value = vector;
+ else if(next_cycle.mul_hi_wb)
+ wr_value = mul_q_hi;
end
always_ff @(posedge clk or negedge rst_n)
@@ -115,45 +94,31 @@ module core_control_writeback
last_rd <= rd;
wb_alu_flags <= alu_flags;
- unique case(next_cycle)
- ISSUE:
- final_rd <= dec.data.rd;
-
- TRANSFER:
- if((cycle != TRANSFER || mem_ready) && pop_valid)
- final_rd <= popped;
-
- BASE_WRITEBACK:
- final_rd <= ra;
-
- EXCEPTION:
- final_rd <= `R14;
- endcase
-
- unique case(next_cycle)
- ISSUE:
- final_writeback <= issue && dec.ctrl.writeback;
-
- EXCEPTION:
- final_writeback <= 1;
- endcase
+ if(next_cycle.issue)
+ final_rd <= dec.data.rd;
+ else if(next_cycle.transfer) begin
+ if((!cycle.transfer || mem_ready) && pop_valid)
+ final_rd <= popped;
+ end else if(next_cycle.base_writeback)
+ final_rd <= ra;
+ else if(next_cycle.exception)
+ final_rd <= `R14;
+
+ if(next_cycle.issue)
+ final_writeback <= issue && dec.ctrl.writeback;
+ else
+ final_writeback <= 1;
update_flags <= 0;
- unique case(next_cycle)
- ISSUE:
- update_flags <= final_update_flags;
-
- EXCEPTION:
- update_flags <= 0;
- endcase
-
- unique case(next_cycle)
- ISSUE:
- final_update_flags <= issue && dec.psr.update_flags;
-
- EXCEPTION:
- final_update_flags <= 0;
- endcase
+ if(next_cycle.issue)
+ update_flags <= final_update_flags;
+ else if(next_cycle.exception)
+ update_flags <= 0;
+
+ if(next_cycle.issue)
+ final_update_flags <= issue && dec.psr.update_flags;
+ else if(next_cycle.exception)
+ final_update_flags <= 0;
end
endmodule
diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv
index 51d7f32..5928d00 100644
--- a/rtl/core/mmu/mmu.sv
+++ b/rtl/core/mmu/mmu.sv
@@ -22,7 +22,7 @@ module core_mmu
data_data_rd
);
- enum
+ enum int unsigned
{
INSN,
DATA
diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv
index 5b88559..d553104 100644
--- a/rtl/core/uarch.sv
+++ b/rtl/core/uarch.sv
@@ -124,7 +124,7 @@ typedef struct packed
logic[5:0] shift_imm;
} snd_decode;
-typedef enum
+typedef enum int unsigned
{
LDST_WORD,
LDST_BYTE,
@@ -181,17 +181,18 @@ typedef struct packed
coproc_decode coproc;
} insn_decode;
-typedef enum
+// Ver comentario en cycles.sv, este diseño es más óptimo
+typedef struct packed
{
- ISSUE,
- RD_INDIRECT_SHIFT,
- WITH_SHIFT,
- TRANSFER,
- BASE_WRITEBACK,
- EXCEPTION,
- MUL,
- MUL_ACC_LD,
- MUL_HI_WB
+ logic issue,
+ rd_indirect_shift,
+ with_shift,
+ transfer,
+ base_writeback,
+ exception,
+ mul,
+ mul_acc_ld,
+ mul_hi_wb;
} ctrl_cycle;
typedef struct packed