Commit 7c857885 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

initial version of the core. prints 'hello world'

parents
sim_tool = "modelsim"
top_module="main"
syn_device="xc6slx150t"
action = "simulation"
target = "xilinx"
include_dirs=["."]
files = [ "main.sv",
"rv_cpu.v",
"rv_exec.v",
"rv_fetch.v",
"rv_predecode.v",
"rv_regfile.v",
"rv_writeback.v"];
/*
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 main;
reg clk = 0;
reg rst = 1;
wire [31:0] im_addr;
reg [31:0] im_data;
wire im_valid = 1'b1;
wire [31:0] dm_addr;
wire [31:0] dm_data_s;
reg [31:0] dm_data_l;
wire [3:0] dm_data_select;
wire dm_write;
localparam int mem_size = 16384;
reg [31:0] mem[0:mem_size - 1];
task automatic load_ram(string filename);
int f = $fopen(filename,"r");
int n, i;
while(!$feof(f))
begin
int addr, data;
string cmd;
$fscanf(f,"%s %08x %08x", cmd,addr,data);
if(cmd == "write")
begin
mem[addr % mem_size] = data;
end
end
endtask // load_ram
always@(posedge clk)
begin
im_data <= mem[(im_addr / 4) % mem_size];
if(dm_write && dm_data_select[0])
mem [(dm_addr / 4) % mem_size][7:0] <= dm_data_s[7:0];
if(dm_write && dm_data_select[1])
mem [(dm_addr / 4) % mem_size][15:8] <= dm_data_s[15:8];
if(dm_write && dm_data_select[2])
mem [(dm_addr / 4) % mem_size][23:16] <= dm_data_s[23:16];
if(dm_write && dm_data_select[3])
mem [(dm_addr / 4) % mem_size][31:24] <= dm_data_s[31:24];
dm_data_l <= mem[(dm_addr/4) % mem_size];
end
rv_cpu DUT
(
.clk_i(clk),
.rst_i(rst),
// instruction mem I/F
.im_addr_o(im_addr),
.im_data_i(im_data),
.im_valid_i(im_valid),
// data mem I/F
.dm_addr_o(dm_addr),
.dm_data_s_o(dm_data_s),
.dm_data_l_i(dm_data_l),
.dm_data_select_o(dm_data_select),
.dm_write_o(dm_write)
);
always #5ns clk <= ~clk;
initial begin
load_ram("sw/hello.ram");
repeat(3) @(posedge clk);
rst = 0;
end
function string decode_op(bit[2:0] fun);
case(fun)
`FUNC_ADD: return "add";
`FUNC_XOR:return "xor";
`FUNC_OR: return "or";
`FUNC_AND:return "and";
`FUNC_SLT:return "slt";
`FUNC_SLTU:return "sltu";
`FUNC_SL: return "sl";
`FUNC_SR:return"sr";
endcase // case (fun)
endfunction // decode_op
function string decode_cond(bit[2:0] fun);
case(fun)
`BRA_EQ: return "eq";
`BRA_NEQ: return "neq";
`BRA_LT: return "lt";
`BRA_GE: return "ge";
`BRA_LTU:return "ltu";
`BRA_GEU:return "geu";
endcase // case (fun)
endfunction // decode_op
function string decode_size(bit[2:0] fun);
case(fun)
`LDST_B: return "s8";
`LDST_BU: return "u8";
`LDST_H: return "s16";
`LDST_HU: return "u16";
`LDST_L:return "32";
endcase // case (fun)
endfunction // decode_op
function string decode_regname(bit[4:0] r);
case(r)
0: return "zero";
1: return "ra";
2: return "sp";
3: return "gp";
4: return "tp";
5: return "t0";
6: return "t1";
7: return "t2";
8: return "s0";
9: return "s1";
10: return "a0";
11: return "a1";
12: return "a2";
13: return "a3";
14: return "a4";
15: return "a5";
16: return "a6";
17: return "a7";
18: return "s2";
19: return "s3";
20: return "s4";
21: return "s5";
22: return "s6";
23: return "s7";
24: return "s8";
25: return "s9";
26: return "s10";
27: return "s11";
28: return "t3";
29: return "t4";
30: return "t5";
31: return "t6";
endcase // case (fun)
endfunction // decode_regname
function automatic string s_hex(int x);
return $sformatf("%s0x%-08x", x<0?"-":" ", (x<0)?(-x):x);
endfunction // s_hex
reg[31:0] dm_addr_d0;
always@(posedge clk)
begin
dm_addr_d0 <= dm_addr;
if(dm_write)
$display("DM Write addr %x data %x", dm_addr, dm_data_s);
if (DUT.writeback.x_load_i)
$display("DM Load addr %x data %x -> %s", dm_addr_d0, dm_data_l, decode_regname(DUT.writeback.x_rd_i));
end
always@(posedge clk)
if(dm_write && dm_addr == 'h100000)
$display("\n ****** TX '%c' \n", dm_data_s[7:0]) ;
always@(posedge clk)
if(!DUT.execute.x_stall_i && !DUT.execute.x_kill_i)
begin
automatic string opc="<unk>", fun="", args="";
automatic string rs1 = decode_regname(DUT.d2x_rs1);
automatic string rs2 = decode_regname(DUT.d2x_rs2);
automatic string rd = decode_regname(DUT.d2x_rd);
reg [31:0] imm;
// $display("Opcode %x", DUT.d2x_opcode);
case (DUT.d2x_opcode)
`OPC_AUIPC:
begin
opc = "auipc";
fun = "";
args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm_u));
end
`OPC_LUI:
begin
opc = "lui";
fun = "";
args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm_u));
end
`OPC_OP_IMM:
begin
opc = "op-imm";
fun = decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s %s", rd, rs1, s_hex(DUT.d2x_imm_i));
end
`OPC_OP:
begin
opc = "op-imm";
fun = decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s %-3s", rd, rs1, rs2);
end
`OPC_JAL:
begin
opc = "jal";
fun = "";
//decode_op(DUT.d2x_fun);
args = $sformatf("%-3s 0x%-08x", rd, DUT.execute.branch_target);
end
`OPC_JALR:
begin
opc = "jalr";
fun = "";
//decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s 0x%-08x", rd, rs1, DUT.execute.branch_target);
end
`OPC_BRANCH:
begin
opc = "branch";
fun = decode_cond(DUT.d2x_fun);
//decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s 0x%-08x %s", rs1, rs2, DUT.execute.branch_target, DUT.execute.branch_take?"TAKE":"IGNORE");
end
`OPC_LOAD:
begin
opc = "ld";
fun = decode_size(DUT.d2x_fun);
//decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s [0x%-08x + %s]", rd, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_i_i)));
end
`OPC_STORE:
begin
opc = "st";
fun = decode_size(DUT.d2x_fun);
//decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s [0x%-08x + %s]", rs2, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_s_i)));
end
endcase // case (d2x_opcode)
$display("%08x: %-8s %-3s %s", DUT.execute.d_pc_i, opc, fun, args);
end
endmodule // main
vlog -sv main.sv +incdir+. +incdir+../../include/wb +incdir+../../include/vme64x_bfm +incdir+../../include +incdir+../include +incdir+../../sim
vsim -t 1ps work.main -voptargs=+acc
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
do wave.do
radix -hexadecimal
run 1.7us
\ No newline at end of file
/*
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_cpu
(
input clk_i,
input rst_i,
// instruction mem I/F
output [31:0] im_addr_o,
input [31:0] im_data_i,
input im_valid_i,
// data mem I/F
output [31:0] dm_addr_o,
output [31:0] dm_data_s_o,
input [31:0] dm_data_l_i,
output [3:0] dm_data_select_o,
output dm_write_o
);
wire f_stall;
wire w_stall;
wire x_stall;
wire x_kill;
wire [31:0] f2d_pc, f2d_ir;
wire f2d_ir_valid;
wire [31:0] x2f_pc_bra;
wire x2f_bra;
rv_fetch fetch
(
.clk_i(clk_i),
.rst_i(rst_i),
.im_addr_o(im_addr_o),
.im_data_i(im_data_i),
.im_valid_i(im_valid_i),
.f_stall_i(f_stall),
.f_ir_o(f2d_ir),
.f_pc_o(f2d_pc),
.f_ir_valid_o(f2d_ir_valid),
.x_pc_bra_i(x2f_pc_bra),
.x_bra_i(x2f_bra)
);
wire [31:0] d2x_pc;
wire [4:0] rf_rs1, d2x_rs1;
wire [4:0] rf_rs2, d2x_rs2;
wire [4:0] d2x_rd;
wire [4:0] d2x_shamt;
wire [2:0] d2x_fun;
wire [4:0] d2x_opcode;
wire d2x_shifter_sign;
wire [31:0] d2x_imm_i, d2x_imm_s, d2x_imm_u, d2x_imm_b, d2x_imm_j;
rv_predecode decode
(
.clk_i(clk_i),
.rst_i(rst_i),
.im_data_i(im_data_i),
.f_ir_i(f2d_ir),
.f_pc_i(f2d_pc),
.x_pc_o(d2x_pc),
.rf_rs1_o(rf_rs1),
.rf_rs2_o(rf_rs2),
.x_rs1_o(d2x_rs1),
.x_rs2_o(d2x_rs2),
.x_rd_o(d2x_rd),
.x_shamt_o(d2x_shamt),
.x_fun_o(d2x_fun),
.x_opcode_o(d2x_opcode),
.x_shifter_sign_o(d2x_shifter_sign),
.x_imm_i_o(d2x_imm_i),
.x_imm_s_o(d2x_imm_s),
.x_imm_b_o(d2x_imm_b),
.x_imm_u_o(d2x_imm_u),
.x_imm_j_o(d2x_imm_j)
);
wire [31:0] x_rs2_value, x_rs1_value;
wire [4:0] rf_rd;
wire [31:0] rf_rd_value;
wire rf_rd_write;
rv_regfile regfile
(
.clk_i(clk_i),
.rst_i(rst_i),
.x_stall_i(x_stall),
.w_stall_i(w_stall),
.rf_rs1_i(rf_rs1),
.rf_rs2_i(rf_rs2),
.d_rs1_i(d2x_rs1),
.d_rs2_i(d2x_rs2),
.x_rs1_value_o(x_rs1_value),
.x_rs2_value_o(x_rs2_value),
.w_rd_i(rf_rd),
.w_rd_value_i(rf_rd_value),
.w_rd_store_i(rf_rd_write)
);
wire [4:0] x2w_rd;
wire [31:0] x2w_rd_value;
wire [31:0] x2w_dm_addr;
wire x2w_rd_write;
wire [2:0] x2w_fun;
rv_exec execute
(
.clk_i(clk_i),
.rst_i(rst_i),
.x_stall_i(x_stall),
.x_kill_i(x_kill),
.x_stall_req_o(x_stall_req),
.d_pc_i(d2x_pc),
.d_rd_i(d2x_rd),
.d_fun_i(d2x_fun),
.rf_rs1_value_i(x_rs1_value),
.rf_rs2_value_i(x_rs2_value),
.d_opcode_i(d2x_opcode),
.d_shifter_sign_i(d2x_shifter_sign),
.d_imm_i_i(d2x_imm_i),
.d_imm_s_i(d2x_imm_s),
.d_imm_b_i(d2x_imm_b),
.d_imm_u_i(d2x_imm_u),
.d_imm_j_i(d2x_imm_j),
.f_branch_target_o (x2f_pc_bra), // fixme: consistent naming
.f_branch_take_o (x2f_bra),
// Writeback stage I/F
.w_fun_o(x2w_fun),
.w_load_o(x2w_load),
.w_dm_addr_o(x2w_dm_addr),
.w_rd_o(x2w_rd),
.w_rd_value_o(x2w_rd_value),
.w_rd_write_o(x2w_rd_write),
.dm_addr_o(dm_addr_o),
.dm_data_s_o(dm_data_s_o),
.dm_data_select_o(dm_data_select_o),
.dm_write_o(dm_write_o)
);
rv_writeback writeback
(
.clk_i(clk_i),
.rst_i(rst_i),
.w_stall_i(w_stall),
.x_fun_i(x2w_fun),
.x_load_i(x2w_load),
.x_rd_i(x2w_rd),
.x_rd_value_i(x2w_rd_value),
.x_rd_write_i(x2w_rd_write),
.x_dm_addr_i(x2w_dm_addr),
.dm_data_l_i(dm_data_l_i),
.rf_rd_value_o(rf_rd_value),
.rf_rd_o(rf_rd),
.rf_rd_write_o(rf_rd_write)
);
reg x_bra_d0;
always@(posedge clk_i)
if(rst_i)
x_bra_d0 <= 0;
else if (!x_stall)
x_bra_d0 <= x2f_bra;
assign f_stall = 0;
assign x_stall = f_stall || (!f2d_ir_valid);
assign w_stall = x_stall;
assign x_kill = x2f_bra && ~x_bra_d0;
endmodule // rv_cpu
/*
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.
*/
`define OPC_OP_IMM 5'b00100
`define OPC_LUI 5'b01101
`define OPC_AUIPC 5'b00101
`define OPC_OP 5'b01100
`define OPC_JAL 5'b11011
`define OPC_JALR 5'b11001
`define OPC_BRANCH 5'b11000
`define OPC_LOAD 5'b00000
`define OPC_STORE 5'b01000
`define BRA_EQ 3'b000
`define BRA_NEQ 3'b001
`define BRA_LT 3'b100
`define BRA_GE 3'b100
`define BRA_LTU 3'b110
`define BRA_GEU 3'b111
`define LDST_B 3'b000
`define LDST_H 3'b001
`define LDST_L 3'b010
`define LDST_BU 3'b100
`define LDST_HU 3'b101
`define FUNC_ADD 3'b000
`define FUNC_SLT 3'b010
`define FUNC_SLTU 3'b011
`define FUNC_XOR 3'b100
`define FUNC_OR 3'b110
`define FUNC_AND 3'b111
`define FUNC_SL 3'b001
`define FUNC_SR 3'b101
/*
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_exec
(
input clk_i,
input rst_i,
input x_stall_i,
input x_kill_i,
output reg x_stall_req_o,
input [31:0] d_pc_i,
input [4:0] d_rd_i,
input [2:0] d_fun_i,
input [31:0] rf_rs1_value_i,
input [31:0] rf_rs2_value_i,
input [4:0] d_opcode_i,
input d_shifter_sign_i,
input [31:0] d_imm_i_i,
input [31:0] d_imm_s_i,
input [31:0] d_imm_b_i,
input [31:0] d_imm_u_i,
input [31:0] d_imm_j_i,
output reg [31:0] f_branch_target_o,
output reg f_branch_take_o,
// Writeback stage I/F
output reg [2:0 ] w_fun_o,
output reg w_load_o,
output reg [4:0] w_rd_o,
output reg [31:0] w_rd_value_o,
output reg w_rd_write_o,
output reg [31:0] w_dm_addr_o,
// Data memory I/F (address/store)
output [31:0] dm_addr_o,
output [31:0] dm_data_s_o,
output [3:0] dm_data_select_o,
// input [31:0] dm_data_l_i,
output dm_write_o
);
wire [31:0] rs1, rs2;
assign rs1 = rf_rs1_value_i;
assign rs2 = rf_rs2_value_i;
reg [31:0] alu_op1, alu_op2, alu_result;
reg [31:0] rd_value;
reg branch_take;
reg branch_condition_met;
reg [31:0] branch_target;
reg [31:0] dm_addr, dm_data_s, dm_select_s;
reg dm_write_s;
reg rd_write;
// branch condition decoding
always@*
case (d_fun_i)
`BRA_EQ: branch_condition_met <= (rs1 == rs2);
`BRA_NEQ: branch_condition_met <= ~(rs1 == rs2);
`BRA_GEU: branch_condition_met <= ($signed(rs1) >= $signed(rs2));
`BRA_LTU: branch_condition_met <= ($signed(rs1) < $signed(rs2));
`BRA_GE: branch_condition_met <= (rs1 >= rs2);
`BRA_LT: branch_condition_met <= (rs1 < rs2);
default: branch_condition_met <= 0;
endcase // case (d_fun_i)
always@*
case (d_opcode_i)
`OPC_JAL: branch_target <= d_pc_i + d_imm_j_i;
`OPC_JALR: branch_target <= rs1 + d_imm_i_i;
`OPC_BRANCH: branch_target <= d_pc_i + d_imm_b_i;
default: branch_target<= 32'hx;
endcase // case (d_opcode_i)
// decode ALU operands
always@*
begin
alu_op1 <= rs1;
alu_op2 <= (d_opcode_i == `OPC_OP_IMM) ? d_imm_i_i : rs2;
end
// the ALU itself
always@*
begin
case (d_fun_i)
`FUNC_ADD: alu_result <= alu_op1 + alu_op2;
`FUNC_XOR: alu_result <= alu_op1 ^ alu_op2;
`FUNC_OR: alu_result <= alu_op1 | alu_op2;
`FUNC_AND: alu_result <= alu_op1 & alu_op2;
`FUNC_SLT: alu_result <= ($signed(alu_op1) < $signed(alu_op2)) ? 1 : 0;
`FUNC_SLTU: alu_result <= ((alu_op1) < (alu_op2)) ? 1 : 0;
`FUNC_SL: alu_result <= alu_op1 << alu_op2[4:0];
`FUNC_SR:
begin
if(d_shifter_sign_i)
alu_result <= $signed(alu_op1) >>> alu_op2[4:0];
else
alu_result <= alu_op1 >> alu_op2[4:0];
end
default: alu_result <= 32'hx;
endcase // case (d_fun_i)
end // always@ *
// rdest write value
always@*
begin
case (d_opcode_i)
`OPC_OP_IMM, `OPC_OP:
begin
rd_value <= alu_result;
rd_write <= 1;
end
`OPC_JAL, `OPC_JALR:
begin
rd_value <= d_pc_i + 4;
rd_write <= 1;
end
`OPC_LUI:
begin
rd_value <= { d_imm_u_i[31:12] , 12'h0 };
rd_write <= 1;
end
`OPC_AUIPC:
begin
rd_value <= d_pc_i + { d_imm_u_i[31:12], 12'h0 };
rd_write <= 1;
end
default:
begin
rd_value <= 32'hx;
rd_write <= 0;
end
endcase
end
// generate load/store address
always@*
begin
case (d_opcode_i)
`OPC_LOAD: dm_addr <= rs1 + d_imm_i_i;
`OPC_STORE: dm_addr <= rs1 + d_imm_s_i;
default: dm_addr <= 32'hx;
endcase // case (d_opcode_i)
end
// generate store value/select
always@*
begin
case (d_fun_i)
`LDST_B:
begin
dm_data_s <= { rs2[7:0], rs2[7:0], rs2[7:0], rs2[7:0] };
dm_select_s[0] <= (dm_addr [1:0] == 2'b00);
dm_select_s[1] <= (dm_addr [1:0] == 2'b01);
dm_select_s[2] <= (dm_addr [1:0] == 2'b10);
dm_select_s[3] <= (dm_addr [1:0] == 2'b11);
end
`LDST_H:
begin
dm_data_s <= { rs2[15:0], rs2[15:0] };
dm_select_s[0] <= (dm_addr [1] == 1'b0);
dm_select_s[1] <= (dm_addr [1] == 1'b1);
end
`LDST_L:
begin
dm_data_s <= rs2;
dm_select_s <= 4'b1111;
end
default:
begin
dm_data_s <= 32'hx;
dm_select_s <= 4'hx;
end
endcase // case (d_fun_i)
end
//branch decision
always@*
case (d_opcode_i)
`OPC_JAL, `OPC_JALR:
branch_take <= 1;
`OPC_BRANCH:
branch_take <= branch_condition_met;
default:
branch_take <= 0;
endcase // case (d_opcode_i)
// generate store write
always@*
begin
dm_write_s <= ( (d_opcode_i == `OPC_STORE) && !x_stall_i );
end
assign dm_addr_o = dm_addr;
assign dm_data_s_o = dm_data_s;
assign dm_data_select_o = dm_select_s;
assign dm_write_o = dm_write_s;
always@(posedge clk_i)
if (rst_i) begin
f_branch_target_o <= 0;
f_branch_take_o <= 0;
x_stall_req_o <= 0;
w_rd_write_o <= 0;
w_rd_o <= 0;
w_fun_o <= 0;
w_load_o <= 0;
w_dm_addr_o <= 0;
end else if (!x_stall_i) begin
f_branch_target_o <= branch_target;
f_branch_take_o <= branch_take && !x_kill_i;
x_stall_req_o <= 0;
w_rd_o <= d_rd_i;
w_rd_value_o <= rd_value;
w_rd_write_o <= rd_write && !x_kill_i;
w_fun_o <= d_fun_i;
w_load_o <= (d_opcode_i == `OPC_LOAD ? 1: 0) && !x_kill_i;
w_dm_addr_o <= dm_addr;
end // if (!x_stall_i)
endmodule
/*
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.
*/
`timescale 1ns/1ps
module rv_fetch
(
input clk_i,
input rst_i,
output [31:0] im_addr_o,
input [31:0] im_data_i,
input im_valid_i,
input f_stall_i,
output [31:0] f_ir_o,
output reg [31:0] f_pc_o,
output reg f_ir_valid_o,
input [31:0] x_pc_bra_i,
input x_bra_i
);
reg [31:0] pc;
reg [31:0] ir;
reg rst_d;
wire [31:0] pc_next = (x_bra_i ? x_pc_bra_i : pc + 4);
assign f_ir_o = ir;
assign im_addr_o = pc_next;
always@(posedge clk_i)
if (rst_i) begin
pc <= -4;
ir <= 0;
f_ir_valid_o <= 0;
rst_d <= 0;
end else begin
rst_d <= 1;
if (!f_stall_i) begin
if(im_valid_i) begin
ir <= im_data_i;
f_ir_valid_o <= rst_d && !x_bra_i;
f_pc_o <= pc;
pc <= pc_next;
end // if (i_valid_i)
end else begin // if (!f_stall_i)
f_ir_valid_o <= 0;
end // else: !if(!f_stall_i)
end // else: !if(rst_i)
endmodule
/*
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_predecode
(
input clk_i,
input rst_i,
input [31:0] im_data_i,
input [31:0] f_ir_i,
input [31:0] f_pc_i,
output [31:0] x_pc_o,
output [4:0] rf_rs1_o,
output [4:0] rf_rs2_o,
output [4:0] x_rs1_o,
output [4:0] x_rs2_o,
output [4:0] x_rd_o,
output [4:0] x_shamt_o,
output [2:0] x_fun_o,
output [4:0] x_opcode_o,
output x_shifter_sign_o,
output [31:0] x_imm_i_o,
output [31:0] x_imm_s_o,
output [31:0] x_imm_b_o,
output [31:0] x_imm_u_o,
output [31:0] x_imm_j_o
);
assign rf_rs1_o = im_data_i [19:15];
assign rf_rs2_o = im_data_i [24:20];
assign x_rs1_o = f_ir_i [19:15];
assign x_rs2_o = f_ir_i [24:20];
assign x_rd_o = f_ir_i [11:7];
assign x_opcode_o = f_ir_i[6:2];
assign x_shamt_o = f_ir_i[24:20];
assign x_fun_o = f_ir_i[14:12];
assign x_shifter_sign_o = f_ir_i[30];
// decoded imm values
assign x_imm_i_o = { {21{ f_ir_i[31] }}, f_ir_i[30:25], f_ir_i[24:21], f_ir_i[20] };
assign x_imm_s_o = { {21{ f_ir_i[31] }}, f_ir_i[30:25], f_ir_i[11:8], f_ir_i[7] };
assign x_imm_b_o = { {20{ f_ir_i[31] }}, f_ir_i[7], f_ir_i[30:25], f_ir_i[11:8], 1'b0 };
assign x_imm_u_o = { f_ir_i[31], f_ir_i[30:20], f_ir_i[19:12], 12'h000 };
assign x_imm_j_o = { {12{f_ir_i[31]}},
f_ir_i[19:12],
f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0};
assign x_pc_o = f_pc_i;
endmodule // rv_predecode
/*
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_regmem
(
input clk_i,
input rst_i,
input [4:0] a1_i,
output [31:0] q1_o,
input [4:0] a2_i,
input [31:0] d2_i,
input we2_i
);
reg [31:0] ram [0:31];
reg [31:0] bypass_r;
reg bypass;
reg [31:0] q1_int;
always@(posedge clk_i)
q1_int <= ram[a1_i];
always@(posedge clk_i)
if(we2_i)
ram[a2_i] <= d2_i;
// bypass logic
always@(posedge clk_i)
if(rst_i)
bypass <= 0;
else
bypass <= we2_i && (a1_i == a2_i);
always@(posedge clk_i)
begin
if(we2_i)
bypass_r <= d2_i;
end
assign q1_o = bypass ? bypass_r : q1_int;
// synthesis translate_off
initial begin : ram_init
integer i;
for(i=0;i<32; i=i+1) begin
ram[i] = 0;
end
end
// synthesis translate_on
endmodule // rv_regmem
module rv_regfile
(
input clk_i,
input rst_i,
input x_stall_i,
input w_stall_i,
input [4:0] rf_rs1_i,
input [4:0] rf_rs2_i,
input [4:0] d_rs1_i,
input [4:0] d_rs2_i,
output [31:0] x_rs1_value_o,
output [31:0] x_rs2_value_o,
input [4:0] w_rd_i,
input [31:0] w_rd_value_i,
input w_rd_store_i
);
wire [31:0] rs1_regfile;
wire [31:0] rs2_regfile;
wire write = (w_rd_store_i && (w_rd_i != 0));
rv_regmem bank0 (
.clk_i(clk_i),
.rst_i (rst_i ),
.a1_i(rf_rs1_i),
.q1_o(rs1_regfile),
.a2_i(w_rd_i),
.d2_i(w_rd_value_i),
.we2_i (write));
rv_regmem bank1 (
.clk_i(clk_i),
.rst_i (rst_i ),
.a1_i(rf_rs2_i),
.q1_o(rs2_regfile),
.a2_i (w_rd_i),
.d2_i (w_rd_value_i),
.we2_i (write)
);
wire rs1_bypass = write && (/*(w_rd_i == rf_rs1_i) ||*/ (w_rd_i == d_rs1_i));
wire rs2_bypass = write && (/*(w_rd_i == rf_rs2_i) ||*/ (w_rd_i == d_rs2_i));
assign x_rs1_value_o = rs1_bypass ? w_rd_value_i : rs1_regfile;
assign x_rs2_value_o = rs2_bypass ? w_rd_value_i : rs2_regfile;
endmodule // rv_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_writeback
(
input clk_i,
input rst_i,
input w_stall_i,
input [2:0] x_fun_i,
input x_load_i,
input [31:0] x_dm_addr_i,
input [4:0] x_rd_i,
input [31:0] x_rd_value_i,
input x_rd_write_i,
input [31:0] dm_data_l_i,
output [31:0] rf_rd_value_o,
output [4:0] rf_rd_o,
output rf_rd_write_o
);
reg [31:0] load_value;
// generate load value
always@*
begin
case (x_fun_i)
`LDST_B:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {{24{dm_data_l_i[7]}}, dm_data_l_i[7:0] };
2'b01: load_value <= {{24{dm_data_l_i[15]}}, dm_data_l_i[15:8] };
2'b10: load_value <= {{24{dm_data_l_i[23]}}, dm_data_l_i[23:16] };
2'b11: load_value <= {{24{dm_data_l_i[31]}}, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_BU:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {24'h0, dm_data_l_i[7:0] };
2'b01: load_value <= {24'h0, dm_data_l_i[15:8] };
2'b10: load_value <= {24'h0, dm_data_l_i[23:16] };
2'b11: load_value <= {24'h0, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_H:
case ( x_dm_addr_i [1:0] )
2'b00, 2'b01: load_value <= {{16{dm_data_l_i[15]}}, dm_data_l_i[15:0] };
2'b10, 2'b11: load_value <= {{16{dm_data_l_i[31]}}, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_HU:
case ( x_dm_addr_i [1:0] )
2'b00, 2'b01: load_value <= {16'h0, dm_data_l_i[15:0] };
2'b10, 2'b11: load_value <= {16'h0, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_L: load_value <= dm_data_l_i;
default: load_value <= 32'hx;
endcase // case (d_fun_i)
end // always@ *
assign rf_rd_value_o = (x_load_i ? load_value : x_rd_value_i );
assign rf_rd_o = (x_rd_i);
assign rf_rd_write_o = (w_stall_i ? 1'b0 : (x_load_i ? 1'b1 : x_rd_write_i ));
endmodule // rv_writeback
# and don't touch the rest unless you know what you're doing.
CROSS_COMPILE ?= /opt/gcc-riscv/bin/riscv64-unknown-elf-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
CFLAGS = -m32
OBJS = crt0.o main.o
LDS = ram.ld
OUTPUT=hello
$(OUTPUT): $(LDS) $(OBJS)
${CC} -m32 -o $(OUTPUT).elf -nostartfiles $(OBJS) -T $(LDS)
${OBJCOPY} -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -D $(OUTPUT).elf > disasm.S
$(SIZE) $(OUTPUT).elf
# ../genramvhd -p wrc_simulation_firmware $(OUTPUT).bin > wrc_simulation_firmware_pkg.vhd
./genraminit $(OUTPUT).bin 1000 > $(OUTPUT).ram
clean:
rm -f $(OUTPUT).elf $(OUTPUT).bin $(OBJS)
%.o: %.S
${CC} -c -m32 $^ -o $@
\ No newline at end of file
.section .boot, "ax", @progbits
.global _start
_start:
la gp, _gp # Initialize global pointer
la sp, _fstack
# clear the bss segment
la t0, _fbss
la t1, _end
1:
#ifdef __riscv64
sd zero,0(t0)
addi t0, t0, 8
#else
sw zero,0(t0)
addi t0, t0, 4
#endif
bltu t0, t1, 1b
call main
\ No newline at end of file
hello.elf: file format elf32-littleriscv
Disassembly of section .boot:
00000000 <_start>:
0: 00000197 auipc gp,0x0
4: 07018193 addi gp,gp,112 # 70 <_gp>
8: 00010117 auipc sp,0x10
c: ff410113 addi sp,sp,-12 # fffc <_fstack>
10: 00000297 auipc t0,0x0
14: 07828293 addi t0,t0,120 # 88 <_fbss>
18: 00000317 auipc t1,0x0
1c: 0b030313 addi t1,t1,176 # c8 <_ebss>
20: 0002a023 sw zero,0(t0)
24: 00428293 addi t0,t0,4
28: fe62ece3 bltu t0,t1,20 <_start+0x20>
2c: 004000ef jal 30 <main>
Disassembly of section .text:
00000030 <main>:
30: fe010113 addi sp,sp,-32
34: 00812e23 sw s0,28(sp)
38: 02010413 addi s0,sp,32
3c: 08002783 lw a5,128(zero)
40: fef42623 sw a5,-20(s0)
44: 01c0006f j 60 <main+0x30>
48: 08402703 lw a4,132(zero)
4c: fec42783 lw a5,-20(s0)
50: 00178693 addi a3,a5,1
54: fed42623 sw a3,-20(s0)
58: 0007c783 lbu a5,0(a5)
5c: 00f72023 sw a5,0(a4)
60: fec42783 lw a5,-20(s0)
64: 0007c783 lbu a5,0(a5)
68: fe0790e3 bnez a5,48 <main+0x18>
6c: 0000006f j 6c <main+0x3c>
Disassembly of section .rodata:
00000070 <.rodata>:
70: 6548 add a0,a0,s2
72: 6c6c add s8,s8,s11
74: 77202c6f jal s8,27e6 <_ebss+0x271e>
78: 646c726f jal tp,c76be <_fstack+0xb76c2>
...
Disassembly of section .sdata:
00000080 <hello>:
80: 0070 li zero,28
...
00000084 <TX_REG>:
84: 0000 unimp
86: 0010 li zero,4
Disassembly of section .bss:
00000088 <_fbss>:
...
Disassembly of section .comment:
00000000 <.comment>:
0: 3a434347 fmsub.d ft6,ft6,ft4,ft7,rmm
4: 2820 lui a6,0x8
6: 29554e47 fmsub.s ft8,fa0,fs5,ft5,rmm
a: 3520 lui a0,0xfffe8
c: 312e beqz a1,b4 <_fbss+0x2c>
e: 302e beqz a1,36 <main+0x6>
...
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2011 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc < 3)
return -1;
FILE *f = fopen(argv[1], "rb");
if (!f)
return -1;
unsigned char x[4];
int i = 0;
int n = atoi(argv[2]);
while (!feof(f)) {
fread(x, 1, 4, f);
printf("write %x %02X%02X%02X%02X\n", i++, x[3], x[2], x[1],
x[0]);
}
for (; i < n;) {
printf("write %x %02X%02X%02X%02X\n", i++, 0, 0, 0, 0);
}
fclose(f);
return 0;
}
This diff is collapsed.
char dupa[64];
const char *hello="Hello, world";
volatile int *TX_REG = 0x100000;
main()
{
char *s = hello;
while(*s) { *TX_REG = *s++; }
for(;;);
}
\ No newline at end of file
OUTPUT_FORMAT("elf32-littleriscv")
ENTRY(_start)
MEMORY
{
ram :
ORIGIN = 0x00000000,
LENGTH = 65536 - 2048
stack :
ORIGIN = 65536 - 2048,
LENGTH = 2048
}
SECTIONS
{
.boot : { *(.boot) } > ram
.text : { *(.text .text.*) } > ram =0
_gp = .;
.rodata : { *(.rodata .rodata.*) } > ram
.data : {
*(.data .data.*)
} > ram
.bss : {
_fbss = .;
*(.bss .bss.*)
*(COMMON)
_ebss = .;
} > ram
PROVIDE(_endram = ORIGIN(stack));
PROVIDE(_fstack = ORIGIN(stack) + LENGTH(stack) - 4);
_end = .;
}
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /main/DUT/clk_i
add wave -noupdate /main/DUT/rst_i
add wave -noupdate -group cpu /main/DUT/clk_i
add wave -noupdate -group cpu /main/DUT/rst_i
add wave -noupdate -group cpu /main/DUT/im_addr_o
add wave -noupdate -group cpu /main/DUT/im_data_i
add wave -noupdate -group cpu /main/DUT/im_valid_i
add wave -noupdate -group cpu /main/DUT/dm_addr_o
add wave -noupdate -group cpu /main/DUT/dm_data_s_o
add wave -noupdate -group cpu /main/DUT/dm_data_l_i
add wave -noupdate -group cpu /main/DUT/dm_data_select_o
add wave -noupdate -group cpu /main/DUT/dm_write_o
add wave -noupdate -group cpu /main/DUT/f_stall
add wave -noupdate -group cpu /main/DUT/f2d_pc
add wave -noupdate -group cpu /main/DUT/f2d_ir
add wave -noupdate -group cpu /main/DUT/f2d_ir_valid
add wave -noupdate -group cpu /main/DUT/x2f_pc_bra
add wave -noupdate -group cpu /main/DUT/x2f_bra
add wave -noupdate -group cpu /main/DUT/d2x_pc
add wave -noupdate -group cpu /main/DUT/rf_rs2
add wave -noupdate -group cpu /main/DUT/rf_rs1
add wave -noupdate -group cpu /main/DUT/d2x_rd
add wave -noupdate -group cpu /main/DUT/d2x_shamt
add wave -noupdate -group cpu /main/DUT/d2x_fun
add wave -noupdate -group cpu /main/DUT/d2x_opcode
add wave -noupdate -group cpu /main/DUT/d2x_shifter_sign
add wave -noupdate -group cpu /main/DUT/d2x_imm_i
add wave -noupdate -group cpu /main/DUT/d2x_imm_s
add wave -noupdate -group cpu /main/DUT/d2x_imm_b
add wave -noupdate -group cpu /main/DUT/d2x_imm_u
add wave -noupdate -group cpu /main/DUT/d2x_imm_j
add wave -noupdate -expand -group fetch /main/DUT/fetch/clk_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/rst_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_addr_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_data_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_valid_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_stall_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_ir_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_pc_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_ir_valid_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/x_pc_bra_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/x_bra_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/pc
add wave -noupdate -expand -group fetch /main/DUT/fetch/pc_next
add wave -noupdate -expand -group fetch /main/DUT/fetch/ir
add wave -noupdate -group decode /main/DUT/decode/clk_i
add wave -noupdate -group decode /main/DUT/decode/rst_i
add wave -noupdate -group decode /main/DUT/decode/f_ir_i
add wave -noupdate -group decode /main/DUT/decode/f_pc_i
add wave -noupdate -group decode /main/DUT/decode/x_pc_o
add wave -noupdate -group decode /main/DUT/decode/rf_rs1_o
add wave -noupdate -group decode /main/DUT/decode/rf_rs2_o
add wave -noupdate -group decode /main/DUT/decode/x_rd_o
add wave -noupdate -group decode /main/DUT/decode/x_shamt_o
add wave -noupdate -group decode /main/DUT/decode/x_fun_o
add wave -noupdate -group decode /main/DUT/decode/x_opcode_o
add wave -noupdate -group decode /main/DUT/decode/x_shifter_sign_o
add wave -noupdate -group decode /main/DUT/decode/x_imm_i_o
add wave -noupdate -group decode /main/DUT/decode/x_imm_s_o
add wave -noupdate -group decode /main/DUT/decode/x_imm_b_o
add wave -noupdate -group decode /main/DUT/decode/x_imm_u_o
add wave -noupdate -group decode /main/DUT/decode/x_imm_j_o
add wave -noupdate -expand -group regfile /main/DUT/regfile/clk_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/rst_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/x_stall_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_stall_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/rf_rs1_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/rf_rs2_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/d_rs1_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/d_rs2_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/x_rs1_value_o
add wave -noupdate -expand -group regfile /main/DUT/regfile/x_rs2_value_o
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_value_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_store_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs1_regfile
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_regfile
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs1_bypass
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_bypass
add wave -noupdate /main/DUT/regfile/bank0/ram
add wave -noupdate -expand -group execute /main/DUT/execute/clk_i
add wave -noupdate -expand -group execute /main/DUT/execute/rst_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_kill_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_req_o
add wave -noupdate -expand -group execute /main/DUT/execute/d_pc_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_rd_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_fun_i
add wave -noupdate -expand -group execute /main/DUT/execute/rf_rs1_value_i
add wave -noupdate -expand -group execute /main/DUT/execute/rf_rs2_value_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_opcode_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_shifter_sign_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_imm_i_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_imm_s_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_imm_b_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_imm_u_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_imm_j_i
add wave -noupdate -expand -group execute /main/DUT/execute/f_branch_target_o
add wave -noupdate -expand -group execute /main/DUT/execute/f_branch_take_o
add wave -noupdate -expand -group execute /main/DUT/execute/w_fun_o
add wave -noupdate -expand -group execute /main/DUT/execute/w_load_o
add wave -noupdate -expand -group execute /main/DUT/execute/w_rd_o
add wave -noupdate -expand -group execute /main/DUT/execute/w_rd_value_o
add wave -noupdate -expand -group execute /main/DUT/execute/w_rd_write_o
add wave -noupdate -expand -group execute /main/DUT/execute/dm_addr_o
add wave -noupdate -expand -group execute /main/DUT/execute/dm_data_s_o
add wave -noupdate -expand -group execute /main/DUT/execute/dm_data_select_o
add wave -noupdate -expand -group execute /main/DUT/execute/dm_write_o
add wave -noupdate -expand -group execute /main/DUT/execute/rs1
add wave -noupdate -expand -group execute /main/DUT/execute/rs2
add wave -noupdate -expand -group execute /main/DUT/execute/alu_op1
add wave -noupdate -expand -group execute /main/DUT/execute/alu_op2
add wave -noupdate -expand -group execute /main/DUT/execute/alu_result
add wave -noupdate -expand -group execute /main/DUT/execute/rd_value
add wave -noupdate -expand -group execute /main/DUT/execute/branch_take
add wave -noupdate -expand -group execute /main/DUT/execute/branch_target
add wave -noupdate -expand -group execute /main/DUT/execute/dm_addr
add wave -noupdate -expand -group execute /main/DUT/execute/dm_data_s
add wave -noupdate -expand -group execute /main/DUT/execute/dm_select_s
add wave -noupdate -expand -group execute /main/DUT/execute/dm_write_s
add wave -noupdate -expand -group execute /main/DUT/execute/rd_write
add wave -noupdate -expand -group writeback /main/DUT/writeback/clk_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/rst_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/w_stall_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_fun_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_load_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_value_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_write_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/dm_data_l_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_value_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_write_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/load_value
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {969304 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {911 ns} {1039 ns}
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