Commit 65e80de2 authored by Tristan Gingold's avatar Tristan Gingold

Merge branch 'proposed_master' into 'master'

Release v1.1

See merge request be-cem-edl/common/urv-core!1
parents 9016844b 1a9e0f86
......@@ -11,4 +11,6 @@ files = [ "urv_cpu.v",
"urv_timer.v",
"urv_exceptions.v",
"urv_iram.v",
"xurv_core.vhd" ];
"urv_ecc.v",
"xurv_core.vhd",
"urv_pkg.vhd" ]
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- uRV - a tiny and dumb RISC-V core
-- https://www.ohwr.org/projects/urv-core
--------------------------------------------------------------------------------
--
-- unit name: na
--
-- description: uRV configuration
--
--------------------------------------------------------------------------------
-- Copyright CERN 2015-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
*/
// Platform definition. Currently supported ones are:
// SPARTAN6 - Xilinx Spartan-6 FPGA
// GENERIC - Generic, HW-independent
`define URV_PLATFORM_SPARTAN6 1
`define URV_PLATFORM_GENERIC 1
//`define URV_PLATFORM_SPARTAN6 1
//`define URV_PLATFORM_ALTERA 1
This diff is collapsed.
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- uRV - a tiny and dumb RISC-V core
-- https://www.ohwr.org/projects/urv-core
--------------------------------------------------------------------------------
--
-- unit name: urv_csr
--
-- description: uRV CSR
--
--------------------------------------------------------------------------------
-- Copyright CERN 2015-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
*/
`include "urv_defs.v"
......@@ -39,7 +44,7 @@ module urv_csr
input [31:0] d_rs1_i,
output reg [31:0] x_rd_o,
output [31:0] x_rd_o,
input [39:0] csr_time_i,
input [39:0] csr_cycles_i,
......@@ -52,12 +57,19 @@ module urv_csr
input [31:0] csr_mip_i,
input [31:0] csr_mie_i,
input [31:0] csr_mepc_i,
input [31:0] csr_mcause_i
input [31:0] csr_mcause_i,
// Debug mailboxes
input [31:0] dbg_mbx_data_i,
input dbg_mbx_write_i,
output [31:0] dbg_mbx_data_o
);
parameter g_with_hw_debug = 0;
reg [31:0] csr_mscratch;
reg [31:0] mbx_data;
reg [31:0] csr_in1;
reg [31:0] csr_in2;
reg [31:0] csr_out;
......@@ -75,11 +87,12 @@ module urv_csr
`CSR_ID_MCAUSE: csr_in1 <= csr_mcause_i;
`CSR_ID_MIP: csr_in1 <= csr_mip_i;
`CSR_ID_MIE: csr_in1 <= csr_mie_i;
default: csr_in1 <= 32'hx;
`CSR_ID_DBGMBX: csr_in1 <= g_with_hw_debug ? mbx_data : 32'h0;
`CSR_ID_MIMPID: csr_in1 <= 32'h20190131;
default: csr_in1 <= 32'h0;
endcase // case (d_csr_sel_i)
always@*
x_rd_o <= csr_in1;
assign x_rd_o = csr_in1;
genvar i;
......@@ -95,8 +108,6 @@ module urv_csr
endcase // case (d_fun_i)
generate
for (i=0;i<32;i=i+1)
begin : gen_csr_bits
......@@ -115,28 +126,31 @@ module urv_csr
csr_out[i] <= 32'hx;
endcase // case (d_csr_op_i)
end // for (i=0;i<32;i=i+1)
endgenerate
always@(posedge clk_i)
if(rst_i)
csr_mscratch <= 0;
else if(!x_stall_i && !x_kill_i && d_is_csr_i)
case (d_csr_sel_i)
`CSR_ID_MSCRATCH:
csr_mscratch <= csr_out;
endcase // case (d_csr_sel_i)
endgenerate
always@(posedge clk_i)
if(rst_i)
begin
csr_mscratch <= 0;
mbx_data <= 0;
end
else
begin
if (dbg_mbx_write_i && g_with_hw_debug)
mbx_data <= dbg_mbx_data_i;
if(!x_stall_i && !x_kill_i && d_is_csr_i)
case (d_csr_sel_i)
`CSR_ID_MSCRATCH:
csr_mscratch <= csr_out;
`CSR_ID_DBGMBX:
if(g_with_hw_debug)
mbx_data <= csr_out;
endcase // case (d_csr_sel_i)
end // else: !if(rst_i)
assign dbg_mbx_data_o = mbx_data;
assign x_csr_write_value_o = csr_out;
endmodule
......@@ -17,7 +17,7 @@ module urv_debug
input x_valid_i,
input [31:0] x_pc_i,
input x_dm_load_i,
input x_dm_store_i,
input [31:0] x_dm_addr_i,
......@@ -46,7 +46,7 @@ module urv_debug
output [31:0] f_pc_restore_o,
output f_pc_restore_load_o,
input [6:0] dbg_adr_i,
input [7:0] dbg_dat_i,
input dbg_stb_i,
......@@ -62,22 +62,22 @@ module urv_debug
`define BREAK_SRC_MEM_ST_DATA 2
`define BREAK_SRC_MEM_LD_DATA 3
reg [31:0] break_compare_hi [0:g_num_breakpoints-1];
reg [31:0] break_compare_lo [0:g_num_breakpoints-1];
reg [1:0] break_src [0:g_num_breakpoints-1];
reg break_valid[0:g_num_breakpoints-1];
reg [31:0] in_muxed[0 : g_num_breakpoints-1];
reg in_valid[0:g_num_breakpoints-1];
reg break_hit[0: g_num_breakpoints-1];
reg in_valid[0:g_num_breakpoints-1];
reg break_hit[0: g_num_breakpoints-1];
`define ST_IDLE 0
generate
genvar gg;
for (gg = 0; gg < g_num_breakpoints; gg = gg + 1)
begin
always@*
......@@ -90,30 +90,30 @@ module urv_debug
endcase // case (break_src[gg])
case (break_src[gg])
`BREAK_SRC_PC:
`BREAK_SRC_PC:
begin
in_muxed[gg] <= x_pc_i;
in_muxed[gg] <= x_pc_i;
in_valid[gg] <= x_valid_i;
end
`BREAK_SRC_MEM_ADDR:
begin
in_muxed[gg] <= x_dm_addr_i;
in_valid[gg] <= x_dm_load_i || x_dm_store_i;
end
`BREAK_SRC_MEM_ST_DATA:
`BREAK_SRC_MEM_ST_DATA:
begin
in_muxed[gg] <= x_dm_data_s_i;
in_valid[gg] <= x_dm_store_i;
end
`BREAK_SRC_MEM_LD_DATA:
`BREAK_SRC_MEM_LD_DATA:
begin
in_muxed[gg] <= dm_data_l_i;
in_valid[gg] <= dm_load_done_i;
end
endcase // case (break_src[gg])
break_hit[gg] <= ( in_muxed[gg] >= break_comp1[gg] && in_muxed[gg] <= break_comp[gg] ) ? in_valid[gg] : 1'b0;
......@@ -125,14 +125,14 @@ module urv_debug
reg trigger_reload_pc;
reg trigger_halt;
reg trigger_resume;
reg [31:0] reload_pc_value;
`define DBG_REG_PC0 0
`define DBG_REG_PC1 1
`define DBG_REG_PC2 2
`define DBG_REG_PC3 3
always@(posedge clk_i)
if(rst_i) begin
......@@ -142,25 +142,25 @@ module urv_debug
trigger_halt <= 0;
trigger_resume <= 0;
trigger_reload_pc <= 0;
if ( dbg_we_i ) begin
case (dbg_adr_i)
`DBG_REG_PCO: reload_pc_value[7:0] <= dbg_dat_i;
`DBG_REG_PC1: reload_pc_value[15:8] <= dbg_dat_i;
`DBG_REG_PC2: reload_pc_value[23:16] <= dbg_dat_i;
`DBG_REG_PC3: reload_pc_value[31:24] <= dbg_dat_i;
`DBG_CTL:
begin
`DBG_CTL:
begin
trigger_halt <= dbg_dat_i[0];
trigger_resume <= dbg_dat_i[1];
trigger_reload_pc <= dbg_dat_i[2];
end
endcase // case (dbg_adr_i)
end else begin // if ( dbg_we_i )
case (dbg_adr_i)
......@@ -169,23 +169,21 @@ module urv_debug
`DBG_REG_PC2: dbg_dat_o <= x_pc_i[23:16];
`DBG_REG_PC3: dbg_dat_o <= x_pc_i[31:24];
end // else: !if( dbg_we_i )
end // else: !if( dbg_we_i )
end
end
end
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- uRV - a tiny and dumb RISC-V core
-- https://www.ohwr.org/projects/urv-core
--------------------------------------------------------------------------------
--
-- unit name: urv_decode
--
-- description: uRV CPU: instruction decode stage
--
--------------------------------------------------------------------------------
-- Copyright CERN 2015-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
*/
`include "urv_defs.v"
......@@ -49,32 +54,38 @@ module urv_decode
output [4:0] x_rs1_o,
output [4:0] x_rs2_o,
output [4:0] x_rd_o,
output reg [4:0] x_shamt_o,
output reg [2:0] x_fun_o,
output [4:0] x_opcode_o,
output reg x_shifter_sign_o,
output reg x_is_signed_compare_o,
output reg x_is_signed_alu_op_o,
output reg x_is_add_o,
output x_is_shift_o,
output reg x_is_load_o,
output reg x_is_store_o,
output reg x_is_undef_o,
output reg x_is_write_ecc_o,
output reg x_is_fix_ecc_o,
output reg [2:0] x_rd_source_o,
output x_rd_write_o,
output reg [11:0] x_csr_sel_o,
output reg [4:0] x_csr_imm_o,
output reg x_is_csr_o,
output reg x_is_eret_o,
output reg x_is_mret_o,
output reg x_is_ebreak_o,
output reg [31:0] x_imm_o,
output reg [31:0] x_alu_op1_o,
output reg [31:0] x_alu_op2_o,
output reg x_use_op1_o,
output reg x_use_op2_o,
output reg [1:0] x_op1_sel_o,
output reg [1:0] x_op2_sel_o
output reg x_use_rs1_o,
output reg x_use_rs2_o,
output reg x_is_divide_o,
output reg x_is_multiply_o
);
parameter g_with_hw_div = 0;
parameter g_with_hw_mul = 0;
parameter g_with_hw_debug = 0;
wire [4:0] f_rs1 = f_ir_i[19:15];
wire [4:0] f_rs2 = f_ir_i[24:20];
wire [4:0] f_rd = f_ir_i[11:7];
......@@ -102,13 +113,11 @@ module urv_decode
reg load_hazard;
// attempt to reuse ALU for jump address generation
wire d_is_shift = (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
wire d_is_shift = !f_ir_i[25] && (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
(d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM );
reg x_is_mul;
wire d_is_mul = (f_ir_i[25] && d_fun == `FUNC_MUL);
wire d_is_mul = (f_ir_i[25] && (d_fun == `FUNC_MUL || d_fun == `FUNC_MULH || d_fun == `FUNC_MULHU || d_fun == `FUNC_MULHSU) );
// hazzard detect combinatorial logic
always@*
......@@ -118,28 +127,26 @@ module urv_decode
`OPC_LOAD:
load_hazard <= 1;
`OPC_OP:
// 2 cycles instructions
load_hazard <= x_is_shift | x_is_mul;
`OPC_OP_IMM:
// 2 cycles instructions
load_hazard <= x_is_shift;
default:
load_hazard <= 0;
endcase // case (x_opcode)
end else
end
else
load_hazard <= 0;
reg inserting_nop;
// bubble insertion following a hazzard
// bubble insertion following a hazard (only 1 bubble).
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
inserting_nop <= load_hazard && !inserting_nop;
assign d_stall_req_o = load_hazard && !inserting_nop;
......@@ -151,7 +158,9 @@ module urv_decode
begin
x_pc_o <= 0;
x_valid <= 0;
end else if(!d_stall_i) begin
end
else if(!d_stall_i)
begin
x_pc_o <= f_pc_i;
if (load_hazard && !inserting_nop)
......@@ -163,11 +172,10 @@ module urv_decode
x_rs2 <= f_rs2;
x_rd <= f_rd;
x_opcode <= d_opcode;
x_shamt_o <= f_ir_i[24:20];
end
// ALU function decoding
// attempt to reuse ALU for jump address generation
always@(posedge clk_i)
if(!d_stall_i)
case (d_opcode)
......@@ -260,6 +268,31 @@ module urv_decode
endcase // case (d_opcode_i)
end // if (!d_stall_i)
always@(posedge clk_i)
if(!d_stall_i)
case (d_opcode)
`OPC_JALR, `OPC_LOAD, `OPC_OP_IMM:
begin
x_use_rs1_o <= 1'b1;
x_use_rs2_o <= 1'b0;
end
`OPC_STORE, `OPC_BRANCH, `OPC_OP, `OPC_CUST2:
begin
x_use_rs1_o <= 1'b1;
x_use_rs2_o <= 1'b1;
end
`OPC_SYSTEM:
begin
x_use_rs1_o <= d_fun[2] == 1'b0 && d_fun[1:0] != 2'b0;
x_use_rs2_o <= 1'b0;
end
default:
begin
x_use_rs1_o <= 1'b0;
x_use_rs2_o <= 1'b0;
end
endcase
wire d_rd_nonzero = (f_rd != 0);
......@@ -269,10 +302,13 @@ module urv_decode
begin
x_is_shift <= d_is_shift;
x_is_load_o <= ( d_opcode == `OPC_LOAD && !load_hazard) ? 1'b1 : 1'b0;
x_is_store_o <= ( d_opcode == `OPC_STORE && !load_hazard) ? 1'b1 : 1'b0;
x_is_mul <= d_is_mul;
x_is_load_o <= d_opcode == `OPC_LOAD && !load_hazard;
x_is_store_o <= d_opcode == `OPC_STORE && !load_hazard;
x_is_mul <= d_is_mul && g_with_hw_mul;
x_is_write_ecc_o <= d_opcode == `OPC_CUST2 && d_fun == `FUNC_WRECC;
x_is_fix_ecc_o <= d_opcode == `OPC_CUST2 && d_fun == `FUNC_FIXECC;
case (d_opcode)
`OPC_BRANCH:
......@@ -283,24 +319,73 @@ module urv_decode
case (d_opcode)
`OPC_OP:
x_is_add_o <= ~f_ir_i[30] && !(d_fun == `FUNC_SLT || d_fun == `FUNC_SLTU);
x_is_add_o <= ~f_ir_i[30];
`OPC_OP_IMM:
x_is_add_o <= !(d_fun == `FUNC_SLT || d_fun == `FUNC_SLTU);
x_is_add_o <= 1;
`OPC_BRANCH:
x_is_add_o <= 0;
default:
x_is_add_o <= 1;
endcase // case (d_opcode)
// all multiply/divide instructions except MUL
x_is_undef_o <= (d_opcode == `OPC_OP && f_ir_i[25] && d_fun != `FUNC_MUL);
// all multiply/divide instructions except
if( d_opcode == `OPC_OP && f_ir_i[25] )
begin
case (d_fun)
`FUNC_MUL:
begin
x_is_multiply_o <= g_with_hw_mul != 0;
x_is_divide_o <= 0;
x_is_undef_o <= g_with_hw_mul == 0;
end
`FUNC_MULH, `FUNC_MULHU, `FUNC_MULHSU:
begin
x_is_multiply_o <= g_with_hw_mul > 1;
x_is_divide_o <= 0;
x_is_undef_o <= g_with_hw_mul <= 1;
end
`FUNC_DIV, `FUNC_DIVU, `FUNC_REM, `FUNC_REMU:
begin
x_is_multiply_o <= 0;
x_is_divide_o <= 1;
x_is_undef_o <= !g_with_hw_div;
end
default:
begin
x_is_multiply_o <= 0;
x_is_divide_o <= 0;
x_is_undef_o <= 0;
end
endcase // case (d_fun)
end else begin // if ( d_opcode == `OPC_OP && f_ir_i[25] )
x_is_multiply_o <= 0;
x_is_divide_o <= 0;
x_is_undef_o <= 0;
end // else: !if( d_opcode == `OPC_OP && f_ir_i[25] )
if(d_is_shift)
x_rd_source_o <= `RD_SOURCE_SHIFTER;
else if (d_opcode == `OPC_SYSTEM)
x_rd_source_o <= `RD_SOURCE_CSR;
else if (d_opcode == `OPC_OP && !d_fun[2] && f_ir_i[25])
x_rd_source_o <= `RD_SOURCE_MULTIPLY;
else if (d_opcode == `OPC_OP && f_ir_i[25])
begin
// mul/div
if( !d_fun[2] )
begin
if( d_fun == `FUNC_MUL )
x_rd_source_o <= `RD_SOURCE_MULTIPLY;
else
x_rd_source_o <= `RD_SOURCE_MULH;
end
else
x_rd_source_o <= `RD_SOURCE_DIVIDE;
end
else
x_rd_source_o <= `RD_SOURCE_ALU;
......@@ -310,6 +395,8 @@ module urv_decode
x_rd_write <= d_rd_nonzero;
`OPC_SYSTEM:
x_rd_write <= d_rd_nonzero && (d_fun != 0); // CSR instructions write to RD
`OPC_CUST2:
x_rd_write <= 1'b1;
default:
x_rd_write <= 0;
endcase // case (d_opcode)
......@@ -323,13 +410,14 @@ module urv_decode
x_csr_imm_o <= f_ir_i[19:15];
x_csr_sel_o <= f_ir_i[31:20];
x_is_csr_o <= (d_opcode == `OPC_SYSTEM) && (d_fun != 0);
x_is_eret_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == 12'b000100000000);
x_is_mret_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == `SYS_IMM_MRET);
if(g_with_hw_debug)
x_is_ebreak_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == `SYS_IMM_EBREAK);
else
x_is_ebreak_o <= 1'b0;
end
assign x_is_shift_o = x_is_shift;
assign x_rd_write_o = x_rd_write;
endmodule // rv_decode
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
--------------------------------------------------------------------------------
-- CERN BE-CO-HT