Commit 24a3f937 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

we run coremark!

parent b25e4d38
......@@ -164,8 +164,8 @@ module rv_cpu
assign TRIG2[3] = f_stall;
assign TRIG2[4] = w_stall_req;
assign TRIG2[5] = x_stall_req;
wire d_stall_req;
......@@ -178,6 +178,8 @@ module rv_cpu
.d_stall_i(d_stall),
.d_kill_i(d_kill),
.d_stall_req_o(d_stall_req),
.f_ir_i(f2d_ir),
.f_pc_i(f2d_pc),
.f_valid_i(f2d_valid),
......@@ -422,7 +424,7 @@ module rv_cpu
-----/\----- EXCLUDED -----/\----- */
assign f_stall = x_stall_req || w_stall_req;
assign f_stall = x_stall_req || w_stall_req || d_stall_req;
// || (interlock_load && !interlock_load_d0);
assign x_stall = x_stall_req || w_stall_req;
// || (interlock_load && !interlock_load_d0);
......
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
`include "rv_defs.v"
`timescale 1ns/1ps
module rv_exceptions
(
input clk_i,
input rst_i,
input x_stall_i,
input x_kill_i,
input d_is_csr_i,
input d_is_eret_i,
input [2:0] d_fun_i,
input [4:0] d_csr_imm_i,
input [11:0] d_csr_sel_i,
input exp_irq_i,
input exp_tick_i,
input exp_breakpoint_i,
input exp_unaligned_load_i,
input exp_unaligned_store_i,
input exp_invalid_insn_i,
input [31:0] x_csr_write_value_i,
output x_exception_o,
input [31:0] x_exception_pc_i,
output [31:0] x_exception_pc_o,
output [31:0] csr_mstatus_o,
output [31:0] csr_mip_o,
output [31:0] csr_mie_o,
output [31:0] csr_mepc_o,
output [31:0] csr_mcause_o
);
reg [31:0] csr_mepc;
reg [31:0] csr_mie;
reg csr_ie;
reg exception;
reg [3:0] cause;
reg [5:0] except_vec_masked;
assign csr_mcause_o = 0;
assign csr_mepc_o = csr_mepc;
assign csr_mie_o = csr_mie;
assign csr_mstatus_o[0] = csr_ie;
assign csr_mstatus_o[31:1] = 0;
reg [31:0] csr_mip;
always@*
begin
csr_mip <= 0;
csr_mip[`EXCEPT_ILLEGAL_INSN] <= except_vec_masked[0];
csr_mip[`EXCEPT_BREAKPOINT] <= except_vec_masked[1];
csr_mip[`EXCEPT_UNALIGNED_LOAD]<= except_vec_masked[2];
csr_mip[`EXCEPT_UNALIGNED_STORE] <= except_vec_masked[3];
csr_mip[`EXCEPT_TIMER] <= except_vec_masked[4];
csr_mip[`EXCEPT_IRQ] <= except_vec_masked[5];
end
assign csr_mip_o = csr_mip;
always@(posedge clk_i)
if (rst_i)
except_vec_masked <= 0;
else begin
if(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP) begin
except_vec_masked[0] <= x_csr_write_value_i [`EXCEPT_ILLEGAL_INSN];
except_vec_masked[1] <= x_csr_write_value_i [`EXCEPT_BREAKPOINT];
except_vec_masked[2] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_LOAD];
except_vec_masked[3] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_STORE];
except_vec_masked[4] <= x_csr_write_value_i [`EXCEPT_TIMER];
except_vec_masked[5] <= x_csr_write_value_i [`EXCEPT_IRQ];
end else begin
if ( exp_invalid_insn_i )
except_vec_masked[0] <= csr_mie[`EXCEPT_ILLEGAL_INSN];
if ( exp_breakpoint_i )
except_vec_masked[1] <= csr_mie[`EXCEPT_BREAKPOINT];
if ( exp_unaligned_load_i )
except_vec_masked[2] <= csr_mie[`EXCEPT_UNALIGNED_LOAD];
if ( exp_unaligned_store_i )
except_vec_masked[3] <= csr_mie[`EXCEPT_UNALIGNED_STORE];
if ( exp_tick_i )
except_vec_masked[4] <= csr_mie[`EXCEPT_TIMER];
if( exp_irq_i )
except_vec_masked[5] <= csr_mie[`EXCEPT_IRQ];
end // else: !if(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP)
end // else: !if(rst_i)
always@*
exception <= |except_vec_masked;
reg exception_pending;
always@(posedge clk_i)
if(rst_i)
begin
csr_mepc <= 0;
csr_mie <= 0;
csr_ie <= 0;
exception_pending <= 0;
end else if(!x_stall_i && !x_kill_i) begin
if ( d_is_eret_i )
exception_pending <= 0;
if ( !exception_pending && exception && csr_ie )
begin
csr_mepc <= x_exception_pc_i;
exception_pending <= 1;
end
if(d_is_csr_i) begin
case (d_csr_sel_i)
`CSR_ID_MSTATUS:
csr_ie <= x_csr_write_value_i[0];
`CSR_ID_MEPC:
csr_mepc <= x_csr_write_value_i;
`CSR_ID_MIE:
begin
csr_mie[`EXCEPT_ILLEGAL_INSN] <= x_csr_write_value_i [`EXCEPT_ILLEGAL_INSN];
csr_mie[`EXCEPT_BREAKPOINT] <= x_csr_write_value_i [`EXCEPT_BREAKPOINT];
csr_mie[`EXCEPT_UNALIGNED_LOAD] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_LOAD];
csr_mie[`EXCEPT_UNALIGNED_STORE] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_STORE];
csr_mie[`EXCEPT_TIMER] <= x_csr_write_value_i [`EXCEPT_TIMER];
csr_mie[`EXCEPT_IRQ] <= x_csr_write_value_i [`EXCEPT_IRQ];
end
endcase // case (d_csr_sel_i)
end // if (d_is_csr_i)
end // if (!x_stall_i && !x_kill_i)
assign x_exception_pc_o = csr_mepc;
assign x_exception_o = exception & csr_ie & !exception_pending;
endmodule // rv_exceptions
......@@ -317,6 +317,26 @@ module rv_exec
end
reg unaligned_addr;
always@*
case (d_fun_i)
`LDST_B,
`LDST_BU:
unaligned_addr <= 0;
`LDST_H,
`LDST_HU:
unaligned_addr <= (dm_addr[0]);
`LDST_L:
unaligned_addr <= (dm_addr[1:0] != 2'b00);
default:
unaligned_addr <= 0;
endcase // case (d_fun_i)
// generate store value/select
always@*
begin
......@@ -413,6 +433,14 @@ module rv_exec
w_fun_o <= d_fun_i;
w_load_o <= is_load && !exception;
w_store_o <= is_store && !exception;
if ( (is_load || is_store) && !exception && unaligned_addr)
begin
$error("Unaligned address!");
$stop;
end
w_dm_addr_o <= dm_addr;
......
......@@ -30,6 +30,8 @@ module rv_decode
input d_stall_i,
input d_kill_i,
output d_stall_req_o,
output reg x_load_hazard_o,
......@@ -37,7 +39,7 @@ module rv_decode
input [31:0] f_pc_i,
input f_valid_i,
output reg x_valid_o,
output x_valid_o,
output reg [31:0] x_pc_o,
......@@ -78,6 +80,7 @@ module rv_decode
reg [4:0] x_rs2;
reg [4:0] x_rd;
reg [4:0] x_opcode;
reg x_valid;
assign x_rs1_o = x_rs1;
assign x_rs2_o = x_rs2;
......@@ -100,28 +103,55 @@ module rv_decode
if(rst_i)
begin
x_pc_o <= 0;
x_valid_o <= 0;
x_valid <= 0;
end else if(!d_stall_i) begin
x_valid_o <= f_valid_i && !d_kill_i;
x_valid <= f_valid_i && !d_kill_i;
x_pc_o <= f_pc_i;
x_ir <= f_ir_i;
end
assign x_valid_o = x_valid;
wire [4:0] d_opcode = f_ir_i[6:2];
/* -----\/----- EXCLUDED -----\/-----
always@(posedge clk_i)
if(!d_stall_i)
x_load_hazard_o <= ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) && (x_opcode == `OPC_LOAD);
-----/\----- EXCLUDED -----/\----- */
wire load_hazard = x_valid && f_valid_i && ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) && (x_opcode == `OPC_LOAD);
reg inserting_nop = 0;
always@(posedge clk_i)
if(rst_i)
inserting_nop <= 0;
else if (!d_stall_i)
begin
if (inserting_nop)
inserting_nop <= 0;
else
inserting_nop <= load_hazard;
end
assign d_stall_req_o = load_hazard && !inserting_nop;
reg load_hazard_d;
always@(posedge clk_i)
if(!d_stall_i)
begin
x_rs1 <= f_rs1;
x_rs2 <= f_rs2;
x_rd <= f_ir_i [11:7];
x_opcode <= d_opcode;
x_rd <= load_hazard ? 0 : f_ir_i [11:7];
x_opcode <= load_hazard ? `OPC_OP : d_opcode;
load_hazard_d <= load_hazard;
x_shamt_o <= f_ir_i[24:20];
end
......@@ -129,13 +159,15 @@ module rv_decode
wire [2:0] d_fun = f_ir_i[14:12];
always@(posedge clk_i)
if(!d_stall_i)
case (d_opcode)
`OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
if(!d_stall_i)
if (load_hazard)
x_fun_o <= `FUNC_ADD;
default:
x_fun_o <= d_fun;
endcase // case (f_opcode)
else case (d_opcode)
`OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_fun_o <= `FUNC_ADD;
default:
x_fun_o <= d_fun;
endcase // case (f_opcode)
always@(posedge clk_i)
if(!d_stall_i)
......@@ -179,7 +211,12 @@ module rv_decode
x_is_signed_compare_o <= ( ( d_opcode == `OPC_BRANCH) && ( ( d_fun == `BRA_GE )|| (d_fun == `BRA_LT ) ) )
|| ( ( (d_opcode == `OPC_OP) || (d_opcode == `OPC_OP_IMM) ) && (d_fun == `FUNC_SLT ) );
x_is_add_o <= (d_opcode == `OPC_JAL) || (!((d_opcode == `OPC_OP && d_fun == `FUNC_ADD && f_ir_i[30]) || (d_fun == `FUNC_SLT) || (d_fun == `FUNC_SLTU)));
x_is_add_o <= (d_opcode == `OPC_AUIPC) || (d_opcode == `OPC_JAL) ||
(d_opcode == `OPC_LUI) || (d_opcode == `OPC_JALR) ||
(!((d_opcode == `OPC_OP && d_fun == `FUNC_ADD && f_ir_i[30]) || (d_fun == `FUNC_SLT) || (d_fun == `FUNC_SLTU)));
x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT);
......@@ -191,6 +228,8 @@ module rv_decode
else
x_rd_source_o <= `RD_SOURCE_ALU;
// rdest write value
case (d_opcode)
`OPC_OP_IMM, `OPC_OP, `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
......
......@@ -142,8 +142,8 @@ module rv_regfile
.we2_i (write)
);
wire rs1_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs1_i);
wire rs2_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs2_i);
wire rs1_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs1_i) && (w_rd_i != 0);
wire rs2_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs2_i) && (w_rd_i != 0);
assign x_rs1_value_o = rs1_bypass ? w_bypass_rd_value_i : rs1_regfile;
assign x_rs2_value_o = rs2_bypass ? w_bypass_rd_value_i : rs2_regfile;
......
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
`include "rv_defs.v"
`timescale 1ns/1ps
module rv_timer
(
input clk_i,
input rst_i,
output [39:0] csr_time_o,
output [39:0] csr_cycles_o,
output sys_tick_o
);
parameter g_timer_frequency = 1000;
parameter g_clock_frequency = 62500000;
localparam g_prescaler = (g_clock_frequency / g_timer_frequency ) - 1;
reg [23:0] presc;
reg presc_tick;
reg [39:0] cycles;
reg [39:0] ticks;
always@(posedge clk_i)
if(rst_i)
begin
presc <= 0;
presc_tick <= 0;
end else begin
if(presc == g_prescaler) begin
presc <= 0;
presc_tick <= 1;
end else begin
presc_tick <= 0;
presc <= presc + 1;
end // else: !if(rst_i)
end // else: !if(rst_i)
always @(posedge clk_i)
if (rst_i)
ticks <= 0;
else if (presc_tick)
ticks <= ticks + 1;
always @(posedge clk_i)
if (rst_i)
cycles <= 0;
else
cycles <= cycles + 1;
assign csr_time_o = ticks;
assign csr_cycles_o = cycles;
assign sys_tick_o = presc_tick;
endmodule // rv_timer
......@@ -121,8 +121,12 @@ module rv_writeback
pending_store <= 0;
end
reg interlock_d = 0;
wire interlock = 0 ;
/* -----\/----- EXCLUDED -----\/-----
reg interlock_d ;
wire interlock = ( ( x_load_i || pending_load ) && dm_load_done_i && (x_load_hazard_i || pending_load_hazard ) );
......@@ -135,6 +139,7 @@ module rv_writeback
else
interlock_d <= interlock;
end
-----/\----- EXCLUDED -----/\----- */
assign rf_rd_value_o = (x_load_i || pending_load ? load_value : x_rd_value_i );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment