Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add state machine to execute stage for multi-operation instructions. …

…Stall fetch/decode while processing multi-op instructions.
  • Loading branch information...
commit 116d8fd87791cf46aa0f8936d47cac32912c4938 1 parent 607c5ff
@atgreen authored
View
950 moxie/cores/moxie/cpu_execute.v
@@ -23,13 +23,18 @@ module cpu_execute (/*AUTOARG*/
// Outputs
register_write_index_o, register_write_enable_o,
memory_read_enable_o, memory_write_enable_o, memory_address_o,
- reg_result_o, mem_result_o, riA_o, riB_o, branch_flag_o,
+ reg_result_o, mem_result_o, riA_o, riB_o, stall_o, branch_flag_o,
branch_target_o,
// Inputs
rst_i, clk_i, stall_i, riA_i, riB_i, regA_i, regB_i,
- register_write_index_i, operand_i, op_i
+ register_write_index_i, operand_i, op_i, sp_i, fp_i
);
+ parameter [1:0] STATE_READY = 2'b00,
+ STATE_JSR1 = 2'b01,
+ STATE_JSR2 = 2'b10,
+ STATE_JSR3 = 2'b11;
+
// --- Clock and Reset ------------------------------------------
input rst_i, clk_i;
@@ -44,6 +49,8 @@ module cpu_execute (/*AUTOARG*/
input [3:0] register_write_index_i;
input [31:0] operand_i;
input [5:0] op_i;
+ input [31:0] sp_i;
+ input [31:0] fp_i;
// --- Outputs --------------------------------------------------
output [3:0] register_write_index_o;
@@ -56,6 +63,9 @@ module cpu_execute (/*AUTOARG*/
output [3:0] riA_o;
output [3:0] riB_o;
+ output [0:0] stall_o;
+ reg [0:0] stall_o;
+
output branch_flag_o;
output [31:0] branch_target_o;
@@ -70,20 +80,26 @@ module cpu_execute (/*AUTOARG*/
reg [31:0] reg_result_o;
reg [31:0] mem_result_o;
+ reg [1:0] current_state, next_state;
+
assign riA_o = riA_i;
assign riB_o = riB_i;
always @(posedge rst_i or posedge clk_i)
- if (rst_i == 1)
+ if (rst_i == 1) begin
branch_flag_o <= 0;
- else
- branch_flag_o <= (op_i == `OP_JMPA);
+ current_state <= STATE_READY;
+ end else begin
+ branch_flag_o <= (op_i == `OP_JMPA) || (op_i == `OP_JSR);
+ current_state <= next_state;
+ end
always @(posedge rst_i or posedge clk_i)
if (rst_i) begin
register_write_enable_o <= 0;
memory_read_enable_o <= 0;
memory_write_enable_o <= 0;
+ stall_o <= 0;
end else
if (stall_i)
begin
@@ -92,394 +108,548 @@ module cpu_execute (/*AUTOARG*/
memory_write_enable_o <= 0;
end
else begin
- case (op_i)
- `OP_ADD_L:
- begin
- reg_result_o <= regA_i + regB_i;
- register_write_enable_o <= 1;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_index_o <= register_write_index_i;
- end
- `OP_AND:
- begin
- reg_result_o <= regA_i & regB_i;
- register_write_enable_o <= 1;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_index_o <= register_write_index_i;
- end
- `OP_ASHL:
- begin
- $display ("Executing OP_ASHL");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_ASHR:
- begin
- $display ("Executing OP_ASHR");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BAD:
- begin
- $display ("Executing OP_BAD");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BEQ:
- begin
- $display ("Executing OP_BEQ");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BGE:
- begin
- $display ("Executing OP_BGE");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BGEU:
- begin
- $display ("Executing OP_BGEU");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BGT:
- begin
- $display ("Executing OP_BGT");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BGTU:
- begin
- $display ("Executing OP_BGTU");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BLE:
- begin
- $display ("Executing OP_BLE");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BLEU:
- begin
- $display ("Executing OP_BLEU");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BLT:
- begin
- $display ("Executing OP_BLT");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BLTU:
- begin
- $display ("Executing OP_BLTU");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BNE:
- begin
- $display ("Executing OP_BNE");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_BRK:
- begin
- $display ("Executing OP_BRK");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_CMP:
- begin
- $display ("Executing OP_CMP");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_DEC:
- begin
- $display ("EXECUTE OP_DEC: 0x%x", operand_i);
- reg_result_o <= regA_i - operand_i;
- register_write_enable_o <= 1;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_index_o <= register_write_index_i;
- end
- `OP_DIV_L:
- begin
- $display ("Executing OP_DIV_L");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_GSR:
- begin
- $display ("Executing OP_GSR");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_INC:
- begin
- $display ("EXECUTE OP_INC: 0x%x", operand_i);
- reg_result_o <= regA_i + operand_i;
- register_write_enable_o <= 1;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_index_o <= register_write_index_i;
- end
- `OP_JMP:
- begin
- branch_target_o <= regA_i;
- register_write_enable_o <= 0;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_JMPA:
- begin
- branch_target_o <= operand_i;
- register_write_enable_o <= 0;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_JSR:
- begin
- $display ("Executing OP_JSR");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_JSRA:
- begin
- $display ("Executing OP_JSRA");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_LDA_B:
- begin
- $display ("Executing OP_LDA_B");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDA_L:
- begin
- memory_address_o <= operand_i;
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDA_S:
- begin
- $display ("Executing OP_LDA_S");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LD_B:
- begin
- $display ("Executing OP_LD_B");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDI_B:
- begin
- $display ("Executing OP_LDI_B");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_LDI_L:
- begin
- $display ("EXECUTE OP_LDI_L: 0x%x", operand_i);
- reg_result_o <= operand_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
- end
- `OP_LDI_S:
- begin
- $display ("Executing OP_LDI_S");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_LD_L:
- begin
- $display ("Executing OP_LD_L");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDO_B:
- begin
- $display ("Executing OP_LDO_B");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDO_L:
- begin
- $display ("Executing OP_LDO_L");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LDO_S:
- begin
- $display ("Executing OP_LDO_S");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LD_S:
- begin
- $display ("Executing OP_LD_S");
- memory_read_enable_o <= 1;
- memory_write_enable_o <= 0;
- end
- `OP_LSHR:
- begin
- $display ("Executing OP_LSHR");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_MOD_L:
- begin
- $display ("Executing OP_MOD_L");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_MOV:
- begin
- reg_result_o <= regB_i;
- memory_write_enable_o <= 0;
- memory_read_enable_o <= 0;
- register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
- end
- `OP_MUL_L:
- begin
- $display ("Executing OP_MUL_L");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_NEG:
- begin
- $display ("Executing OP_NEG");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_NOP:
- begin
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_enable_o <= 0;
- end
- `OP_NOT:
- begin
- $display ("Executing OP_NOT");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_OR:
- begin
- reg_result_o <= regA_i | regB_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
- end
- `OP_POP:
- begin
- $display ("Executing OP_POP");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_PUSH:
- begin
- // Decrement pointer register by 4 bytes.
- reg_result_o <= regA_i - 4;
- memory_address_o <= regA_i - 4;
- mem_result_o <= regB_i;
+ case (current_state)
+ STATE_READY:
+ begin
+ case (op_i)
+ `OP_ADD_L:
+ begin
+ reg_result_o <= regA_i + regB_i;
+ register_write_enable_o <= 1;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_AND:
+ begin
+ reg_result_o <= regA_i & regB_i;
+ register_write_enable_o <= 1;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_ASHL:
+ begin
+ $display ("Executing OP_ASHL");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_ASHR:
+ begin
+ $display ("Executing OP_ASHR");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BAD:
+ begin
+ $display ("Executing OP_BAD");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BEQ:
+ begin
+ $display ("Executing OP_BEQ");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BGE:
+ begin
+ $display ("Executing OP_BGE");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BGEU:
+ begin
+ $display ("Executing OP_BGEU");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BGT:
+ begin
+ $display ("Executing OP_BGT");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BGTU:
+ begin
+ $display ("Executing OP_BGTU");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BLE:
+ begin
+ $display ("Executing OP_BLE");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BLEU:
+ begin
+ $display ("Executing OP_BLEU");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BLT:
+ begin
+ $display ("Executing OP_BLT");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BLTU:
+ begin
+ $display ("Executing OP_BLTU");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BNE:
+ begin
+ $display ("Executing OP_BNE");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_BRK:
+ begin
+ $display ("Executing OP_BRK");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_CMP:
+ begin
+ $display ("Executing OP_CMP");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_DEC:
+ begin
+ $display ("EXECUTE OP_DEC: 0x%x", operand_i);
+ reg_result_o <= regA_i - operand_i;
+ register_write_enable_o <= 1;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_DIV_L:
+ begin
+ $display ("Executing OP_DIV_L");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_GSR:
+ begin
+ $display ("Executing OP_GSR");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_INC:
+ begin
+ $display ("EXECUTE OP_INC: 0x%x", operand_i);
+ reg_result_o <= regA_i + operand_i;
+ register_write_enable_o <= 1;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_JMP:
+ begin
+ branch_target_o <= regA_i;
+ register_write_enable_o <= 0;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_JMPA:
+ begin
+ branch_target_o <= operand_i;
+ register_write_enable_o <= 0;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_JSR:
+ begin
+ // Decrement $sp by 8 bytes.
+ reg_result_o <= sp_i - 8;
+ memory_address_o <= sp_i - 8;
+ // FIXME: this should be PC
+ mem_result_o <= regB_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 1;
+ register_write_enable_o <= 1;
+ register_write_index_o <= 1; // $sp
+ next_state <= STATE_JSR1;
+ stall_o <= 1;
+ end
+ `OP_JSRA:
+ begin
+ $display ("Executing OP_JSRA");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_JSR1;
+ stall_o <= 1;
+ end
+ `OP_LDA_B:
+ begin
+ $display ("Executing OP_LDA_B");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDA_L:
+ begin
+ memory_address_o <= operand_i;
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDA_S:
+ begin
+ $display ("Executing OP_LDA_S");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LD_B:
+ begin
+ $display ("Executing OP_LD_B");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDI_B:
+ begin
+ $display ("Executing OP_LDI_B");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDI_L:
+ begin
+ $display ("EXECUTE OP_LDI_L: 0x%x", operand_i);
+ reg_result_o <= operand_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDI_S:
+ begin
+ $display ("Executing OP_LDI_S");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LD_L:
+ begin
+ $display ("Executing OP_LD_L");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDO_B:
+ begin
+ $display ("Executing OP_LDO_B");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDO_L:
+ begin
+ $display ("Executing OP_LDO_L");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LDO_S:
+ begin
+ $display ("Executing OP_LDO_S");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LD_S:
+ begin
+ $display ("Executing OP_LD_S");
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_LSHR:
+ begin
+ $display ("Executing OP_LSHR");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_MOD_L:
+ begin
+ $display ("Executing OP_MOD_L");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_MOV:
+ begin
+ reg_result_o <= regB_i;
+ memory_write_enable_o <= 0;
+ memory_read_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_MUL_L:
+ begin
+ $display ("Executing OP_MUL_L");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_NEG:
+ begin
+ $display ("Executing OP_NEG");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_NOP:
+ begin
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_NOT:
+ begin
+ $display ("Executing OP_NOT");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_OR:
+ begin
+ reg_result_o <= regA_i | regB_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_POP:
+ begin
+ // Decrement pointer register by 4 bytes.
+ memory_address_o <= regA_i;
+ mem_result_o <= regA_i - 4;
+ memory_read_enable_o <= 1;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_PUSH:
+ begin
+ // Decrement pointer register by 4 bytes.
+ reg_result_o <= regA_i - 4;
+ memory_address_o <= regA_i - 4;
+ mem_result_o <= regB_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 1;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_RET:
+ begin
+ $display ("Executing OP_RET");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_SSR:
+ begin
+ $display ("Executing OP_SSR");
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STA_B:
+ begin
+ $display ("Executing OP_STA_B");
+ mem_result_o <= regA_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 1;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STA_L:
+ begin
+ mem_result_o <= regA_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 1;
+ memory_address_o <= operand_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STA_S:
+ begin
+ $display ("Executing OP_STA_S");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_ST_B:
+ begin
+ $display ("Executing OP_ST_B");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_ST_L:
+ begin
+ $display ("Executing OP_ST_L");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STO_B:
+ begin
+ $display ("Executing OP_STO_B");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STO_L:
+ begin
+ $display ("Executing OP_STO_L");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_STO_S:
+ begin
+ $display ("Executing OP_STO_S");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_ST_S:
+ begin
+ $display ("Executing OP_ST_S");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_SUB_L:
+ begin
+ reg_result_o <= regA_i - regB_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_SWI:
+ begin
+ $display ("Executing OP_SWI");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_UDIV_L:
+ begin
+ $display ("Executing OP_UDIV_L");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_UMOD_L:
+ begin
+ $display ("Executing OP_UMOD_L");
+ next_state <= STATE_READY;
+ stall_o <= 0;
+ end
+ `OP_XOR:
+ begin
+ reg_result_o <= regA_i ^ regB_i;
+ memory_read_enable_o <= 0;
+ memory_write_enable_o <= 0;
+ register_write_enable_o <= 1;
+ register_write_index_o <= register_write_index_i;
+ stall_o <= 0;
+ end
+ endcase // case (op_i)
+ end // case: STATE_READY
+ STATE_JSR1:
+ begin
+ // Decrement $sp by 4 bytes.
+ reg_result_o <= sp_i - 4;
+ memory_address_o <= sp_i - 4;
+ mem_result_o <= fp_i;
memory_read_enable_o <= 0;
memory_write_enable_o <= 1;
register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
- end
- `OP_RET:
- begin
- $display ("Executing OP_RET");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_SSR:
- begin
- $display ("Executing OP_SSR");
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- end
- `OP_STA_B:
- begin
- $display ("Executing OP_STA_B");
- mem_result_o <= regA_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 1;
- end
- `OP_STA_L:
- begin
- mem_result_o <= regA_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 1;
- memory_address_o <= operand_i;
- end
- `OP_STA_S:
- begin
- $display ("Executing OP_STA_S");
- end
- `OP_ST_B:
- begin
- $display ("Executing OP_ST_B");
- end
- `OP_ST_L:
- begin
- $display ("Executing OP_ST_L");
- end
- `OP_STO_B:
- begin
- $display ("Executing OP_STO_B");
- end
- `OP_STO_L:
- begin
- $display ("Executing OP_STO_L");
- end
- `OP_STO_S:
- begin
- $display ("Executing OP_STO_S");
- end
- `OP_ST_S:
- begin
- $display ("Executing OP_ST_S");
- end
- `OP_SUB_L:
- begin
- reg_result_o <= regA_i - regB_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
- end
- `OP_SWI:
- begin
- $display ("Executing OP_SWI");
- end
- `OP_UDIV_L:
- begin
- $display ("Executing OP_UDIV_L");
- end
- `OP_UMOD_L:
- begin
- $display ("Executing OP_UMOD_L");
- end
- `OP_XOR:
- begin
- reg_result_o <= regA_i ^ regB_i;
- memory_read_enable_o <= 0;
- memory_write_enable_o <= 0;
- register_write_enable_o <= 1;
- register_write_index_o <= register_write_index_i;
+ register_write_index_o <= 1; // $sp
+ branch_target_o <= operand_i;
+ next_state <= STATE_READY;
+ stall_o <= 0;
end
endcase
end
View
12 moxie/cores/moxie/cpu_registerfile.v
@@ -19,10 +19,10 @@
module cpu_registerfile (/*AUTOARG*/
// Outputs
- value1_o, value2_o,
+ value1_o, value2_o, sp_o, fp_o,
// Inputs
- rst_i, clk_i, write_enable_i, reg_write_index_i,
- reg_read_index1_i, reg_read_index2_i, value_i
+ rst_i, clk_i, write_enable_i, reg_write_index_i, reg_read_index1_i,
+ reg_read_index2_i, value_i
);
// --- Clock and Reset ------------------------------------------
@@ -35,12 +35,18 @@ module cpu_registerfile (/*AUTOARG*/
input [31:0] value_i;
output [31:0] value1_o;
output [31:0] value2_o;
+
+ output [31:0] sp_o;
+ output [31:0] fp_o;
wire [31:0] value1_o = registers[reg_read_index1_i];
wire [31:0] value2_o = registers[reg_read_index2_i];
reg [31:0] registers[0:15];
+ assign fp_o = registers[0];
+ assign sp_o = registers[1];
+
always @ (posedge rst_i or posedge clk_i) begin
if (rst_i) begin
registers[0] <= 32'b00000000000000000000000000000000;
View
1  moxie/cores/moxie/defines.v
@@ -81,4 +81,3 @@
`define OP_UMOD_L 6'b111101
`define OP_XOR 6'b111110
-
View
19 moxie/cores/moxie/moxie.v
@@ -79,6 +79,10 @@ module moxie (/*AUTOARG*/
wire [3:0] dx_regB;
wire [3:0] dx_regC;
+ // Stack and frame pointers
+ wire [31:0] rx_sp;
+ wire [31:0] rx_fp;
+
wire [0:0] xf_branch_flag;
wire [31:0] xf_branch_target;
@@ -89,6 +93,8 @@ module moxie (/*AUTOARG*/
wire [3:0] xr_reg_index1;
wire [3:0] xr_reg_index2;
+ wire [0:0] stall_x;
+
wire [0:0] hazard_war;
reg [0:0] wb_I_stb_o;
@@ -116,7 +122,9 @@ module moxie (/*AUTOARG*/
.write_enable_i (wr_register_write_enable),
.reg_write_index_i (wr_register_write_index),
.reg_read_index1_i (xr_reg_index1),
- .reg_read_index2_i (xr_reg_index2),
+ .reg_read_index2_i (xr_reg_index2),
+ .sp_o (rx_sp),
+ .fp_o (rx_fp),
.value_i (wr_reg_result));
always @(posedge clk_i)
@@ -141,7 +149,7 @@ module moxie (/*AUTOARG*/
.clk_i (clk_i),
.branch_flag_i (xf_branch_flag),
.branch_target_i (xf_branch_target),
- .stall_i (hazard_war),
+ .stall_i (hazard_war | stall_x),
.imem_data_i (wb_I_dat_i[31:0]));
cpu_decode stage_decode (// Inputs
@@ -150,7 +158,7 @@ module moxie (/*AUTOARG*/
.opcode_i (fd_opcode[15:0]),
.operand_i (fd_operand[31:0]),
.valid_i (fd_valid),
- .stall_i (hazard_war),
+ .stall_i (hazard_war | stall_x),
// Outputs
.register_write_enable_o (dx_register_write_enable),
.register_write_index_o (dx_register_write_index),
@@ -163,6 +171,7 @@ module moxie (/*AUTOARG*/
.rst_i (rst_i),
.clk_i (clk_i),
.stall_i (hazard_war),
+ .stall_o (stall_x),
.op_i (dx_op),
.operand_i (dx_operand[31:0]),
.riA_i (dx_reg_index1),
@@ -181,7 +190,9 @@ module moxie (/*AUTOARG*/
.mem_result_o (xw_mem_result),
.memory_address_o (xw_memory_address),
.memory_read_enable_o (xw_loadp),
- .memory_write_enable_o (xw_memory_we));
+ .memory_write_enable_o (xw_memory_we),
+ .sp_i (rx_sp),
+ .fp_i (rx_fp));
cpu_write stage_write ( // Inputs
.rst_i (rst_i),
Please sign in to comment.
Something went wrong with that request. Please try again.