Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/1/head v2.0
liangkangnan 2020-03-29 23:19:14 +08:00
parent 7d9dc3f83a
commit ecb9fca8c1
47 changed files with 443531 additions and 36931 deletions

View File

@ -6,22 +6,22 @@
本人是一名FPGA小白为了快速入门、深入掌握RISC-V我开始了学习FPGA和verilog的&quot;艰难&quot;历程。我工作的内容是和嵌入式软件相关的平时根本不会接触到FPGA也不会用到RISC-V因此只能用业余时间来学习RISC-V。
网上有不少关于RISC-V的开源项目但是大多都写得很&quot;高深&quot;对于我这种小白来说学习起来是非常吃力的不太适合入门。本项目目前的代码量非常少是很简单易懂的对于想入门RISC-V的同学来说是一个很好的参考希望能吸引更多的同学能够参与到RISC-V的学习中来促进RISC-V的发展如果能起到抛砖引玉的作用的话那就更好了也许说是砖的话或者有点夸大了,但哪怕是起到一颗沙子的作用,也就足矣
网上有不少关于RISC-V的开源项目但是大多都写得很&quot;高深&quot;对于我这种小白来说学习起来是非常吃力的不太适合入门。本项目目前的代码量非常少是很简单易懂的对于想入门RISC-V的同学来说是一个很好的参考希望能吸引更多的同学能够参与到RISC-V的学习中来促进RISC-V的发展如果能起到抛砖引玉的作用的话那就更好了也许说是砖的话有点夸大了,但哪怕是起到一颗沙子的作用,也就足矣。
# 2.介绍
本项目实现的是一个微RISC-V处理器核(tinyriscv)用verilog语言编写只求以最简单、最通俗易懂的方式实现RISC-V指令的功能因此没有特意去对代码做任何的优化因此你会看到里面写的代码有很多冗余的地方。tinyriscv处理器核有以下特点:
本项目实现的是一个小型RISC-V处理器核(tinyriscv)采用verilog语言编写。tinyriscv有以下特点:
1. 支持RV32I指令集通过riscv的RV32I指令兼容性测试支持以下指令add addi and andi auipc beq bge bgeu blt bltu bne fence\_i jal jalr lb lbu lh lhu lw lui or ori sb sh sw sll slli slt slti sltiu sltu sra srai srl srli sub xor xori
2. 支持RV32M指令集mul mulh mulhu mulhsu div divu rem remu
3. 采用三级流水线(二级变长),即取指,译码、访存、执行,回写;
4. 可以运行简单的c语言程序
1. 支持RV32IM指令集通过RISC-V指令兼容性测试
3. 采用三级流水线,即取指,译码、执行;
4. 可以运行C语言程序
5. 支持JTAG可以通过openocd读写内存(在线更新程序)
6. 支持中断;
6. 支持总线;
项目中的各目录说明:
**rtl**该目录包含tinyriscv的所有verilog源码
**rtl**该目录包含tinyriscv的所有verilog源码
**sim**该目录包含仿真的顶层testbench代码和批处理bat文件
@ -65,11 +65,21 @@ tinyriscv的整体框架如下
# 4.未来计划
1. 支持总线;
2. ......
1. 完善代码注释;
2. 写设计文档;
3. 支持FreeRTOS
4. ......
# 5.更新记录
2020-03-29重大更新主要更新如下
1. 支持RIB(RISC-V Internal Bus)总线;
2. 优化乘法代码节省了2/3的DSP资源
3. 优化除法代码解决了除法模块的BUG
4. 完善C语言例程、启动代码和链接脚本
5. 增加一次性对所有指令进行测试的脚本;
2020-03-08支持中断为此增加了timer模块来验证。
2020-03-01支持JTAG配合openocd可进行内存读写。JTAG文档参考[深入浅出RISC-V调试](https://liangkangnan.gitee.io/2020/03/21/深入浅出RISC-V调试/)。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 58 KiB

56
rtl/core/clint.v Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// core local interruptor module
module clint(
input wire clk,
input wire rst,
input wire we_i, // write enable
input wire[`RegAddrBus] addr_i, // addr
input wire[`RegBus] data_i, // write data
output reg[`RegBus] data_o // read data
);
reg[`RegBus] regs[0:`RegNum - 1];
// write reg
always @ (posedge clk) begin
if (rst == `RstEnable) begin
regs[0] <= `ZeroWord;
end else begin
if (we_i == `WriteEnable) begin
regs[addr_i] <= data_i;
end
end
end
always @ (*) begin
if (rst == `RstEnable) begin
data_o <= `ZeroWord;
end else begin
data_o <= regs[addr_i];
end
end
endmodule

67
rtl/core/ctrl.v Normal file
View File

@ -0,0 +1,67 @@
/*
Copyright 2019 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
module ctrl(
input wire rst,
input wire jump_flag_i,
input wire[`InstAddrBus] jump_addr_i,
input wire hold_flag_ex_i,
input wire hold_flag_rib_i,
input wire jtag_halt_flag_i,
input wire[`INT_BUS] int_flag_i,
input wire[`InstAddrBus] int_return_addr_i,
output reg[`Hold_Flag_Bus] hold_flag_o,
output reg jump_flag_o,
output reg[`InstAddrBus] jump_addr_o
);
always @ (*) begin
if (rst == `RstEnable) begin
hold_flag_o <= `Hold_None;
jump_flag_o <= `JumpDisable;
jump_addr_o <= `ZeroWord;
end else begin
jump_addr_o <= jump_addr_i;
jump_flag_o <= jump_flag_i;
hold_flag_o <= `Hold_None;
if (int_flag_i == `INT_TIMER0) begin
jump_addr_o <= `INT_TIMER0_ENTRY_ADDR;
jump_flag_o <= `JumpEnable;
hold_flag_o <= `Hold_Id;
end else if (int_flag_i == `INT_RET) begin
jump_addr_o <= int_return_addr_i;
jump_flag_o <= `JumpEnable;
hold_flag_o <= `Hold_Id;
end else if (jump_flag_i == `JumpEnable || hold_flag_ex_i == `HoldEnable) begin
hold_flag_o <= `Hold_Id;
end else if (hold_flag_rib_i == `HoldEnable) begin
hold_flag_o <= `Hold_Pc;
end else if (jtag_halt_flag_i == `HoldEnable) begin
hold_flag_o <= `Hold_Id;
end else begin
hold_flag_o <= `Hold_None;
end
end
end
endmodule

View File

@ -14,6 +14,8 @@
limitations under the License.
*/
`define CpuResetAddr 32'h00000000
`define RstEnable 1'b0
`define RstDisable 1'b1
`define ZeroWord 32'h00000000
@ -21,8 +23,6 @@
`define WriteDisable 1'b0
`define ReadEnable 1'b1
`define ReadDisable 1'b0
`define InstValid 1'b1
`define InstInvalid 1'b0
`define True 1'b1
`define False 1'b0
`define ChipEnable 1'b1
@ -35,6 +35,26 @@
`define DivStop 1'b0
`define HoldEnable 1'b1
`define HoldDisable 1'b0
`define Stop 1'b1
`define NoStop 1'b0
`define RIB_ACK 1'b1
`define RIB_NACK 1'b0
`define RIB_REQ 1'b1
`define RIB_NREQ 1'b0
`define INT_ASSERT 1'b1
`define INT_DEASSERT 1'b0
`define INT_BUS 7:0
`define INT_NONE 8'h0
`define INT_RET 8'hff
`define INT_TIMER0 8'b00000001
`define INT_TIMER0_ENTRY_ADDR 32'h4
`define Hold_Flag_Bus 2:0
`define Hold_None 3'b000
`define Hold_Pc 3'b001
`define Hold_If 3'b010
`define Hold_Id 3'b011
// I type inst
`define INST_TYPE_I 7'b0010011
@ -90,6 +110,7 @@
`define INST_AUIPC 7'b0010111
`define INST_NOP 32'h00000001
`define INST_MRET 32'h30200073
`define INST_RET 32'h00008067
`define INST_FENCE 7'b0001111
@ -102,15 +123,19 @@
`define INST_BLTU 3'b110
`define INST_BGEU 3'b111
// SIM RAM
`define SramMemNum 2048 // memory depth(how many words)
`define SramBus 31:0
`define SramAddrBus 31:0
`define RomNum 2048 // rom depth(how many words)
`define MemNum 2048 // memory depth(how many words)
`define MemBus 31:0
`define MemAddrBus 31:0
`define InstBus 31:0
`define InstAddrBus 31:0
// common regs
`define RegAddrBus 4:0
`define RegBus 31:0
`define DoubleRegBus 63:0
`define RegWidth 32
`define RegNum 32 // reg count
`define RegNum 32 // reg num
`define RegNumLog2 5

View File

@ -17,7 +17,7 @@
`include "defines.v"
module div (
module div(
input wire clk,
input wire rst,
@ -25,17 +25,21 @@ module div (
input wire[`RegBus] dividend_i,
input wire[`RegBus] divisor_i,
input wire start_i,
input wire[2:0] op_i,
input wire[`RegAddrBus] reg_waddr_i,
output reg[`DoubleRegBus] result_o,
output reg ready_o
output reg ready_o,
output wire busy_o,
output reg[2:0] op_o,
output reg[`RegAddrBus] reg_waddr_o
);
parameter STATE_IDLE = 0;
parameter STATE_START = 1;
parameter STATE_REVERT = 2;
parameter STATE_END = 3;
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_INVERT = 2;
localparam STATE_END = 3;
reg[`RegBus] dividend_temp;
reg[`RegBus] divisor_temp;
@ -45,6 +49,10 @@ module div (
reg[`RegBus] div_remain;
reg[`RegBus] minuend;
reg[`RegBus] divisor_zero_result;
reg invert_result;
assign busy_o = (state != STATE_IDLE)? `True : `False;
always @ (posedge clk) begin
@ -55,30 +63,52 @@ module div (
div_result <= `ZeroWord;
div_remain <= `ZeroWord;
divisor_zero_result <= ~32'b00000001 + 1'b1;
op_o <= 3'h0;
reg_waddr_o <= `ZeroWord;
dividend_temp <= `ZeroWord;
divisor_temp <= `ZeroWord;
invert_result <= 1'b0;
end else begin
case (state)
STATE_IDLE: begin
if (start_i == `DivStart) begin
op_o <= op_i;
reg_waddr_o <= reg_waddr_i;
if (divisor_i == `ZeroWord) begin
ready_o <= `DivResultReady;
result_o <= {`ZeroWord, divisor_zero_result};
result_o <= {dividend_i, divisor_zero_result};
end else begin
count <= 7'd31;
state <= STATE_START;
if (dividend_i[31] == 1'b1) begin
dividend_temp <= ~dividend_i + 1;
minuend <= ((~dividend_i + 1) >> 7'd31) & 1'b1;
div_result <= `ZeroWord;
div_remain <= `ZeroWord;
if ((op_i == `INST_DIV) || (op_i == `INST_REM)) begin
if (dividend_i[31] == 1'b1) begin
dividend_temp <= ~dividend_i + 1;
minuend <= ((~dividend_i + 1) >> 7'd31) & 1'b1;
end else begin
dividend_temp <= dividend_i;
minuend <= (dividend_i >> 7'd31) & 1'b1;
end
if (divisor_i[31] == 1'b1) begin
divisor_temp <= ~divisor_i + 1;
end else begin
divisor_temp <= divisor_i;
end
end else begin
dividend_temp <= dividend_i;
minuend <= (dividend_i >> 7'd31) & 1'b1;
end
if (divisor_i[31] == 1'b1) begin
divisor_temp <= ~divisor_i + 1;
end else begin
divisor_temp <= divisor_i;
end
div_result <= `ZeroWord;
div_remain <= `ZeroWord;
if (((op_i == `INST_DIV) && (dividend_i[31] ^ divisor_i[31] == 1'b1))
|| ((op_i == `INST_REM) && (dividend_i[31] == 1'b1))) begin
invert_result <= 1'b1;
end else begin
invert_result <= 1'b0;
end
end
end else begin
ready_o <= `DivResultNotReady;
@ -98,7 +128,7 @@ module div (
end
count <= count - 1'b1;
end else begin
state <= STATE_REVERT;
state <= STATE_INVERT;
if (minuend >= divisor_temp) begin
div_result <= (div_result << 1'b1) | 1'b1;
div_remain <= minuend - divisor_temp;
@ -114,12 +144,10 @@ module div (
end
end
STATE_REVERT: begin
STATE_INVERT: begin
if (start_i == `DivStart) begin
if (dividend_i[31] ^ divisor_i[31] == 1'b1) begin
if (invert_result == 1'b1) begin
div_result <= ~div_result + 1'b1;
end
if (((dividend_i[31] == 1'b1) && (div_remain >= 0)) || ((dividend_i[31] == 1'b0) && (div_remain < 0))) begin
div_remain <= ~div_remain + 1'b1;
end
state <= STATE_END;
@ -137,6 +165,7 @@ module div (
state <= STATE_IDLE;
end else begin
state <= STATE_IDLE;
result_o <= {`ZeroWord, `ZeroWord};
ready_o <= `DivResultNotReady;
end
end

File diff suppressed because it is too large Load Diff

View File

@ -17,33 +17,35 @@
`include "defines.v"
// identification module
module id (
module id(
input wire clk,
input wire rst,
input wire[`SramBus] inst_i, // inst content
input wire[`SramAddrBus] inst_addr_i, // inst addr
input wire jump_flag_ex_i,
input wire hold_flag_ex_i,
input wire int_flag_ex_i,
input wire halt_flag_dm_i,
// from if_id
input wire[`InstBus] inst_i, // inst content
input wire[`InstAddrBus] inst_addr_i, // inst addr
// from regs
input wire[`RegBus] reg1_rdata_i, // reg1 read data
input wire[`RegBus] reg2_rdata_i, // reg2 read data
// from ex
input wire ex_jump_flag_i,
input wire[`INT_BUS] ex_int_flag_i,
// to regs
output reg reg1_re_o, // reg1 read enable
output reg[`RegAddrBus] reg1_raddr_o, // reg1 read addr
output reg reg2_re_o, // reg2 read enable
output reg[`RegAddrBus] reg2_raddr_o, // reg2 read addr
output reg reg_we_o, // reg write enable
output reg[`RegAddrBus] reg_waddr_o, // reg write addr
output wire mem_req_o,
// to ex
output reg[`SramBus] inst_o,
output reg inst_valid_o, // inst is valid flag
output reg[`SramAddrBus] inst_addr_o,
// to sram
output reg sram_re_o, // ram read enable
output reg sram_we_o // ram write enable
output reg[`InstBus] inst_o,
output reg[`InstAddrBus] inst_addr_o,
output reg[`RegBus] reg1_rdata_o, // reg1 read data
output reg[`RegBus] reg2_rdata_o, // reg2 read data
output reg reg_we_o, // reg write enable
output reg[`RegAddrBus] reg_waddr_o // reg write addr
);
@ -54,109 +56,85 @@ module id (
wire[4:0] rs1 = inst_i[19:15];
wire[4:0] rs2 = inst_i[24:20];
reg mem_req;
always @ (posedge clk) begin
assign mem_req_o = ((mem_req == `RIB_REQ) && (ex_jump_flag_i == `JumpDisable) && (ex_int_flag_i == `INT_NONE));
always @ (*) begin
if (rst == `RstEnable) begin
inst_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
sram_we_o <= `WriteDisable;
reg1_re_o <= `ReadDisable;
reg2_re_o <= `ReadDisable;
sram_re_o <= `ReadDisable;
inst_valid_o <= `InstInvalid;
end else if (halt_flag_dm_i == 1'b1) begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
inst_o <= `INST_NOP;
end else if (int_flag_ex_i == 1'b1 && inst_i != `INST_NOP) begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
inst_addr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
inst_o <= `INST_NOP;
end else if (jump_flag_ex_i == `JumpEnable && inst_i != `INST_NOP) begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
inst_o <= `INST_NOP;
end else if (hold_flag_ex_i == `HoldEnable) begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
inst_o <= `INST_NOP;
reg_waddr_o <= `ZeroWord;
mem_req <= `RIB_NREQ;
end else begin
inst_o <= inst_i;
inst_addr_o <= inst_addr_i;
reg1_rdata_o <= reg1_rdata_i;
reg2_rdata_o <= reg2_rdata_i;
mem_req <= `RIB_NREQ;
case (opcode)
`INST_TYPE_I: begin
case (funct3)
`INST_ADDI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_SLTI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_SLTIU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_XORI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_ORI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_ANDI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_SLLI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
`INST_SRI: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
sram_we_o <= `WriteDisable;
reg2_raddr_o <= `ZeroWord;
end
default: begin
inst_valid_o <= `InstInvalid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
endcase
end
@ -164,366 +142,287 @@ module id (
if ((funct7 == 7'b0000000) || (funct7 == 7'b0100000)) begin
case (funct3)
`INST_ADD_SUB: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_SLL: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_SLT: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_SLTU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_XOR: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_SR: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_OR: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_AND: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
default: begin
inst_valid_o <= `InstInvalid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
endcase
end else if (funct7 == 7'b0000001) begin
case (funct3)
`INST_MUL: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_MULHU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_MULH: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_MULHSU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_DIV: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_DIVU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_REM: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
`INST_REMU: begin
inst_valid_o <= `InstValid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= rd;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
end
default: begin
inst_valid_o <= `InstInvalid;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
endcase
end else begin
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
end
`INST_TYPE_L: begin
case (funct3)
`INST_LB: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
sram_re_o <= `ReadEnable;
sram_we_o <= `WriteDisable;
mem_req <= `RIB_REQ;
end
`INST_LH: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
sram_re_o <= `ReadEnable;
sram_we_o <= `WriteDisable;
mem_req <= `RIB_REQ;
end
`INST_LW: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
sram_re_o <= `ReadEnable;
sram_we_o <= `WriteDisable;
mem_req <= `RIB_REQ;
end
`INST_LBU: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
sram_re_o <= `ReadEnable;
sram_we_o <= `WriteDisable;
mem_req <= `RIB_REQ;
end
`INST_LHU: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
sram_re_o <= `ReadEnable;
sram_we_o <= `WriteDisable;
mem_req <= `RIB_REQ;
end
default: begin
inst_valid_o <= `InstInvalid;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
endcase
end
`INST_TYPE_S: begin
case (funct3)
`INST_SB: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteEnable;
sram_re_o <= `ReadEnable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
mem_req <= `RIB_REQ;
end
`INST_SH: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteEnable;
sram_re_o <= `ReadEnable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
mem_req <= `RIB_REQ;
end
`INST_SW: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_re_o <= `ReadEnable;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteEnable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
mem_req <= `RIB_REQ;
end
default: begin
inst_valid_o <= `InstInvalid;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
endcase
end
`INST_TYPE_B: begin
case (funct3)
`INST_BEQ: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
`INST_BNE: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
`INST_BLT: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
`INST_BGE: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
`INST_BLTU: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
`INST_BGEU: begin
inst_valid_o <= `InstValid;
reg1_re_o <= `ReadEnable;
reg2_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= rs2;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
default: begin
inst_valid_o <= `InstInvalid;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
end
endcase
end
`INST_JAL: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
`INST_JALR: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteEnable;
reg1_re_o <= `ReadEnable;
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_waddr_o <= rd;
end
`INST_LUI: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
`INST_AUIPC: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
`INST_NOP: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
`INST_FENCE: begin
inst_valid_o <= `InstValid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
default: begin
inst_valid_o <= `InstInvalid;
sram_we_o <= `WriteDisable;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
endcase
end

70
rtl/core/id_ex.v Normal file
View File

@ -0,0 +1,70 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// identification to execute module
module id_ex(
input wire clk,
input wire rst,
input wire[`InstBus] inst_i, // inst content
input wire[`InstAddrBus] inst_addr_i, // inst addr
input wire reg_we_i,
input wire[`RegAddrBus] reg_waddr_i,
input wire[`RegBus] reg1_rdata_i, // reg1 read data
input wire[`RegBus] reg2_rdata_i, // reg2 read data
input wire[`Hold_Flag_Bus] hold_flag_i,
output reg[`InstBus] inst_o, // inst content
output reg[`InstAddrBus] inst_addr_o, // inst addr
output reg reg_we_o,
output reg[`RegAddrBus] reg_waddr_o,
output reg[`RegBus] reg1_rdata_o, // reg1 read data
output reg[`RegBus] reg2_rdata_o // reg2 read data
);
always @ (posedge clk) begin
if (rst == `RstEnable) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
end else begin
if (hold_flag_i >= `Hold_Id) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
end else begin
inst_o <= inst_i;
inst_addr_o <= inst_addr_i;
reg_we_o <= reg_we_i;
reg_waddr_o <= reg_waddr_i;
reg1_rdata_o <= reg1_rdata_i;
reg2_rdata_o <= reg2_rdata_i;
end
end
end
endmodule

View File

@ -17,38 +17,26 @@
`include "defines.v"
// inst fetch module
module if_id (
module if_id(
input wire clk,
input wire rst,
input wire[`SramBus] inst_i, // inst content
input wire[`SramAddrBus] inst_addr_i, // inst addr
input wire[`InstBus] inst_i, // inst content
input wire[`InstAddrBus] inst_addr_i, // inst addr
input wire jump_flag_ex_i,
input wire hold_flag_ex_i,
input wire int_flag_ex_i,
input wire dm_halt_req_i,
input wire[`Hold_Flag_Bus] hold_flag_i,
output reg[`SramBus] inst_o,
output reg[`SramAddrBus] inst_addr_o
output reg[`InstBus] inst_o,
output reg[`InstAddrBus] inst_addr_o
);
always @ (posedge clk) begin
if (rst == `RstEnable) begin
inst_o <= `ZeroWord;
inst_addr_o <= `ZeroWord;
end else if (dm_halt_req_i == 1'b1) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
end else if (int_flag_ex_i == 1'b1) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
end else if (jump_flag_ex_i == `JumpEnable) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
end else if (hold_flag_ex_i == `HoldEnable) begin
end else if (hold_flag_i >= `Hold_If) begin
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
end else begin

View File

@ -17,56 +17,30 @@
`include "defines.v"
// pc reg module
module pc_reg (
module pc_reg(
input wire clk,
input wire rst,
input wire jump_flag_ex_i,
input wire[`RegBus] jump_addr_ex_i,
input wire jump_flag_i,
input wire[`InstAddrBus] jump_addr_i,
input wire[`Hold_Flag_Bus] hold_flag_i,
input wire jtag_reset_flag_i,
input wire hold_flag_ex_i,
input wire[`RegBus] hold_addr_ex_i,
input wire int_flag_ex_i,
input wire[`RegBus] int_addr_ex_i,
input wire dm_halt_req_i,
input wire dm_reset_req_i,
output reg[`SramAddrBus] pc_o,
output reg re_o
output reg[`InstAddrBus] pc_o
);
reg[`SramAddrBus] offset;
always @ (posedge clk) begin
if (rst == `RstEnable || dm_reset_req_i == 1'b1) begin
pc_o <= `ZeroWord;
offset <= `ZeroWord;
end else if (dm_halt_req_i == 1'b1) begin
pc_o <= offset;
end else if (int_flag_ex_i == 1'b1) begin
pc_o <= int_addr_ex_i;
offset <= int_addr_ex_i + 4'h4;
end else if (jump_flag_ex_i == `JumpEnable) begin
pc_o <= jump_addr_ex_i;
offset <= jump_addr_ex_i + 4'h4;
end else if (hold_flag_ex_i == `HoldEnable) begin
pc_o <= hold_addr_ex_i;
offset <= hold_addr_ex_i;
if (rst == `RstEnable || jtag_reset_flag_i == 1'b1) begin
pc_o <= `CpuResetAddr;
end else if (jump_flag_i == `JumpEnable) begin
pc_o <= jump_addr_i;
end else if (hold_flag_i >= `Hold_Pc) begin
pc_o <= pc_o;
end else begin
pc_o <= offset;
offset <= offset + 4'h4;
end
end
always @ (posedge clk) begin
if (rst == `RstEnable) begin
re_o <= `ReadDisable;
end else begin
re_o <= `ReadEnable;
pc_o <= pc_o + 4'h4;
end
end

56
rtl/core/ram.v Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright 2019 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// ram module
module ram(
input wire clk,
input wire rst,
input wire we_i, // write enable
input wire[`MemAddrBus] addr_i, // addr
input wire[`MemBus] data_i,
input wire req_i,
output reg[`MemBus] data_o, // read data
output reg ack_o
);
reg[`MemBus] _ram[0:`MemNum - 1];
always @ (posedge clk) begin
if (rst == `RstEnable) begin
ack_o <= `RIB_ACK;
end else begin
if (we_i == `WriteEnable) begin
_ram[addr_i[31:2]] <= data_i;
end
end
end
always @ (*) begin
if (rst == `RstEnable) begin
data_o <= `ZeroWord;
end else begin
data_o <= _ram[addr_i[31:2]];
end
end
endmodule

View File

@ -17,22 +17,26 @@
`include "defines.v"
// common reg module
module regs (
module regs(
input wire clk,
input wire rst,
input wire we, // reg write enable
input wire[`RegAddrBus] waddr, // reg write addr
input wire[`RegBus] wdata, // reg write data
input wire we_i, // reg write enable
input wire[`RegAddrBus] waddr_i, // reg write addr
input wire[`RegBus] wdata_i, // reg write data
input wire re1, // reg1 read enable
input wire[`RegAddrBus] raddr1, // reg1 read addr
output reg[`RegBus] rdata1, // reg1 read data
input wire jtag_we_i, // reg write enable
input wire[`RegAddrBus] jtag_addr_i, // reg write addr
input wire[`RegBus] jtag_data_i, // reg write data
input wire re2, // reg2 read enable
input wire[`RegAddrBus] raddr2, // reg2 read addr
output reg[`RegBus] rdata2 // reg2 read data
input wire[`RegAddrBus] raddr1_i, // reg1 read addr
output reg[`RegBus] rdata1_o, // reg1 read data
input wire[`RegAddrBus] raddr2_i, // reg2 read addr
output reg[`RegBus] rdata2_o, // reg2 read data
output reg[`RegBus] jtag_data_o
);
@ -41,35 +45,48 @@ module regs (
// write reg
always @ (posedge clk) begin
if (rst == `RstDisable) begin
if((we == `WriteEnable) && (waddr != `RegNumLog2'h0)) begin
regs[waddr] <= wdata;
if ((we_i == `WriteEnable) && (waddr_i != `RegNumLog2'h0)) begin
regs[waddr_i] <= wdata_i;
end else if ((jtag_we_i == `WriteEnable) && (jtag_addr_i != `RegNumLog2'h0)) begin
regs[jtag_addr_i] <= jtag_data_i;
end
end
end
// read reg1
always @ (*) begin
if(rst == `RstEnable) begin
rdata1 <= `ZeroWord;
end else if(raddr1 == `RegNumLog2'h0) begin
rdata1 <= `ZeroWord;
end else if(re1 == `ReadEnable) begin
rdata1 <= regs[raddr1];
if (rst == `RstEnable) begin
rdata1_o <= `ZeroWord;
end else if (raddr1_i == `RegNumLog2'h0) begin
rdata1_o <= `ZeroWord;
end else if (raddr1_i == waddr_i && we_i == `WriteEnable) begin
rdata1_o <= wdata_i;
end else begin
rdata1 <= `ZeroWord;
rdata1_o <= regs[raddr1_i];
end
end
// read reg2
always @ (*) begin
if(rst == `RstEnable) begin
rdata2 <= `ZeroWord;
end else if(raddr2 == `RegNumLog2'h0) begin
rdata2 <= `ZeroWord;
end else if(re2 == `ReadEnable) begin
rdata2 <= regs[raddr2];
if (rst == `RstEnable) begin
rdata2_o <= `ZeroWord;
end else if (raddr2_i == `RegNumLog2'h0) begin
rdata2_o <= `ZeroWord;
end else if (raddr2_i == waddr_i && we_i == `WriteEnable) begin
rdata2_o <= wdata_i;
end else begin
rdata2 <= `ZeroWord;
rdata2_o <= regs[raddr2_i];
end
end
// jtag read reg
always @ (*) begin
if (rst == `RstEnable) begin
jtag_data_o <= `ZeroWord;
end else if (jtag_addr_i == `RegNumLog2'h0) begin
jtag_data_o <= `ZeroWord;
end else begin
jtag_data_o <= regs[jtag_addr_i];
end
end

300
rtl/core/rib.v Normal file
View File

@ -0,0 +1,300 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
module rib(
input wire clk,
input wire rst,
// master 0 interface
input wire[`MemAddrBus] m0_addr_i,
input wire[`MemBus] m0_data_i,
output reg[`MemBus] m0_data_o,
output reg m0_ack_o,
input wire m0_req_i,
input wire m0_we_i,
// master 1 interface
input wire[`MemAddrBus] m1_addr_i,
input wire[`MemBus] m1_data_i,
output reg[`MemBus] m1_data_o,
output reg m1_ack_o,
input wire m1_req_i,
input wire m1_we_i,
// master 2 interface
input wire[`MemAddrBus] m2_addr_i,
input wire[`MemBus] m2_data_i,
output reg[`MemBus] m2_data_o,
output reg m2_ack_o,
input wire m2_req_i,
input wire m2_we_i,
// slave 0 interface
output reg[`MemAddrBus] s0_addr_o,
output reg[`MemBus] s0_data_o,
input wire[`MemBus] s0_data_i,
input wire s0_ack_i,
output reg s0_req_o,
output reg s0_we_o,
// slave 1 interface
output reg[`MemAddrBus] s1_addr_o,
output reg[`MemBus] s1_data_o,
input wire[`MemBus] s1_data_i,
input wire s1_ack_i,
output reg s1_req_o,
output reg s1_we_o,
// slave 2 interface
output reg[`MemAddrBus] s2_addr_o,
output reg[`MemBus] s2_data_o,
input wire[`MemBus] s2_data_i,
input wire s2_ack_i,
output reg s2_req_o,
output reg s2_we_o,
output reg hold_flag_o
);
parameter [3:0]slave_0 = 4'b0000;
parameter [3:0]slave_1 = 4'b0001;
parameter [3:0]slave_2 = 4'b0010;
parameter [1:0]grant0 = 2'h0;
parameter [1:0]grant1 = 2'h1;
parameter [1:0]grant2 = 2'h2;
wire[2:0] req;
reg[1:0] grant;
reg[1:0] next_grant;
assign req = {m2_req_i, m1_req_i, m0_req_i};
always @ (posedge clk) begin
if (rst == `RstEnable) begin
grant <= grant1;
end else begin
grant <= next_grant;
end
end
// arb
always @ (*) begin
if (rst == `RstEnable) begin
next_grant <= grant1;
hold_flag_o <= `HoldDisable;
end else begin
case (grant)
grant0: begin
if (req[0]) begin
next_grant <= grant0;
hold_flag_o <= `HoldEnable;
end else if (req[2]) begin
next_grant <= grant2;
hold_flag_o <= `HoldEnable;
end else begin
next_grant <= grant1;
hold_flag_o <= `HoldDisable;
end
end
grant1: begin
if (req[0]) begin
next_grant <= grant0;
hold_flag_o <= `HoldEnable;
end else if (req[2]) begin
next_grant <= grant2;
hold_flag_o <= `HoldEnable;
end else begin
next_grant <= grant1;
hold_flag_o <= `HoldDisable;
end
end
grant2: begin
if (req[0]) begin
next_grant <= grant0;
hold_flag_o <= `HoldEnable;
end else if (req[2]) begin
next_grant <= grant2;
hold_flag_o <= `HoldEnable;
end else begin
next_grant <= grant1;
hold_flag_o <= `HoldDisable;
end
end
default: begin
next_grant <= grant1;
hold_flag_o <= `HoldDisable;
end
endcase
end
end
always @ (*) begin
if (rst == `RstEnable) begin
m0_ack_o <= `RIB_NACK;
m1_ack_o <= `RIB_NACK;
m2_ack_o <= `RIB_NACK;
m0_data_o <= `ZeroWord;
m1_data_o <= `INST_NOP;
m2_data_o <= `ZeroWord;
s0_addr_o <= `ZeroWord;
s1_addr_o <= `ZeroWord;
s2_addr_o <= `ZeroWord;
s0_data_o <= `ZeroWord;
s1_data_o <= `ZeroWord;
s2_data_o <= `ZeroWord;
s0_req_o <= `RIB_NREQ;
s1_req_o <= `RIB_NREQ;
s2_req_o <= `RIB_NREQ;
s0_we_o <= `WriteDisable;
s1_we_o <= `WriteDisable;
s2_we_o <= `WriteDisable;
end else begin
m0_ack_o <= `RIB_NACK;
m1_ack_o <= `RIB_NACK;
m2_ack_o <= `RIB_NACK;
m0_data_o <= `ZeroWord;
m1_data_o <= `INST_NOP;
m2_data_o <= `ZeroWord;
s0_addr_o <= `ZeroWord;
s1_addr_o <= `ZeroWord;
s2_addr_o <= `ZeroWord;
s0_data_o <= `ZeroWord;
s1_data_o <= `ZeroWord;
s2_data_o <= `ZeroWord;
s0_req_o <= `RIB_NREQ;
s1_req_o <= `RIB_NREQ;
s2_req_o <= `RIB_NREQ;
s0_we_o <= `WriteDisable;
s1_we_o <= `WriteDisable;
s2_we_o <= `WriteDisable;
case (grant)
grant0: begin
case (m0_addr_i[31:28])
slave_0: begin
s0_req_o <= m0_req_i;
s0_we_o <= m0_we_i;
s0_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
s0_data_o <= m0_data_i;
m0_ack_o <= s0_ack_i;
m0_data_o <= s0_data_i;
end
slave_1: begin
s1_req_o <= m0_req_i;
s1_we_o <= m0_we_i;
s1_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
s1_data_o <= m0_data_i;
m0_ack_o <= s1_ack_i;
m0_data_o <= s1_data_i;
end
slave_2: begin
s2_req_o <= m0_req_i;
s2_we_o <= m0_we_i;
s2_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
s2_data_o <= m0_data_i;
m0_ack_o <= s2_ack_i;
m0_data_o <= s2_data_i;
end
default: begin
end
endcase
end
grant1: begin
case (m1_addr_i[31:28])
slave_0: begin
s0_req_o <= m1_req_i;
s0_we_o <= m1_we_i;
s0_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
s0_data_o <= m1_data_i;
m1_ack_o <= s0_ack_i;
m1_data_o <= s0_data_i;
end
slave_1: begin
s1_req_o <= m1_req_i;
s1_we_o <= m1_we_i;
s1_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
s1_data_o <= m1_data_i;
m1_ack_o <= s1_ack_i;
m1_data_o <= s1_data_i;
end
slave_2: begin
s2_req_o <= m1_req_i;
s2_we_o <= m1_we_i;
s2_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
s2_data_o <= m1_data_i;
m1_ack_o <= s2_ack_i;
m1_data_o <= s2_data_i;
end
default: begin
end
endcase
end
grant2: begin
case (m2_addr_i[31:28])
slave_0: begin
s0_req_o <= m2_req_i;
s0_we_o <= m2_we_i;
s0_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
s0_data_o <= m2_data_i;
m2_ack_o <= s0_ack_i;
m2_data_o <= s0_data_i;
end
slave_1: begin
s1_req_o <= m2_req_i;
s1_we_o <= m2_we_i;
s1_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
s1_data_o <= m2_data_i;
m2_ack_o <= s1_ack_i;
m2_data_o <= s1_data_i;
end
slave_2: begin
s2_req_o <= m2_req_i;
s2_we_o <= m2_we_i;
s2_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
s2_data_o <= m2_data_i;
m2_ack_o <= s2_ack_i;
m2_data_o <= s2_data_i;
end
default: begin
end
endcase
end
default: begin
end
endcase
end
end
endmodule

56
rtl/core/rom.v Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
module rom(
input wire clk,
input wire rst,
input wire we_i, // write enable
input wire[`MemAddrBus] addr_i, // addr
input wire[`MemBus] data_i,
input wire req_i,
output reg[`MemBus] data_o, // read data
output reg ack_o
);
reg[`MemBus] _rom[0:`RomNum - 1];
always @ (posedge clk) begin
if (rst == `RstEnable) begin
ack_o <= `RIB_ACK;
end else begin
if (we_i == `WriteEnable) begin
_rom[addr_i[31:2]] <= data_i;
end
end
end
always @ (*) begin
if (rst == `RstEnable) begin
data_o <= `ZeroWord;
end else begin
data_o <= _rom[addr_i[31:2]];
end
end
endmodule

View File

@ -1,112 +0,0 @@
/*
Copyright 2019 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// simulation ram module
module sim_ram (
input wire clk,
input wire rst,
input wire we_i, // write enable
input wire[`SramAddrBus] waddr_i, // write addr
input wire[`SramBus] wdata_i, // write data
input wire dm_we_i, // dm write enable
input wire[`SramAddrBus] dm_addr_i, // dm write or read addr
input wire[`SramBus] dm_wdata_i, // dm write data
output reg[`SramBus] dm_rdata_o, // dm read data
input wire pc_re_i, // pc read enable
input wire[`SramAddrBus] pc_raddr_i, // pc read addr
output reg[`SramBus] pc_rdata_o, // pc read data
input wire ex_re_i, // ex read enable
input wire[`SramAddrBus] ex_raddr_i, // ex read addr
output reg[`SramBus] ex_rdata_o, // ex read data
output wire we_o,
input wire[`SramBus] rdata_i
);
reg[`SramBus] ram[0:`SramMemNum - 1];
reg[`SramBus] rom[0:`SramMemNum - 1];
assign we_o = (waddr_i >= 32'h10000000) ? 1'b1 : 1'b0;
// ex write mem
always @ (posedge clk) begin
if (rst == `RstDisable) begin
if (we_i == `WriteEnable) begin
ram[waddr_i[13:2]] <= wdata_i;
end
end
end
// dm write rom
always @ (posedge clk) begin
if (rst == `RstDisable) begin
if (dm_we_i == `WriteEnable) begin
rom[dm_addr_i[13:2]] <= dm_wdata_i;
end
end
end
// pc read inst
always @ (*) begin
if (rst == `RstEnable) begin
pc_rdata_o <= `ZeroWord;
end else if ((pc_raddr_i == waddr_i) && (pc_re_i == `ReadEnable)) begin
pc_rdata_o <= wdata_i;
end else if (pc_re_i == `ReadEnable) begin
if (pc_raddr_i < (`SramMemNum - 1)) begin
pc_rdata_o <= rom[pc_raddr_i >> 2];
end else begin
pc_rdata_o <= `INST_NOP;
end
end else begin
pc_rdata_o <= `INST_NOP;
end
end
// ex read mem
always @ (*) begin
if (rst == `RstEnable) begin
ex_rdata_o <= `ZeroWord;
end else if (ex_re_i == `ReadEnable) begin
if (ex_raddr_i < 32'h10000000) begin
ex_rdata_o <= ram[ex_raddr_i[13:2]];
end else begin
ex_rdata_o <= rdata_i;
end
end else begin
ex_rdata_o <= `ZeroWord;
end
end
// dm read rom
always @ (*) begin
if (rst == `RstEnable) begin
dm_rdata_o <= `ZeroWord;
end else begin
dm_rdata_o <= rom[dm_addr_i[13:2]];
end
end
endmodule

274
rtl/core/tinyriscv.v Normal file
View File

@ -0,0 +1,274 @@
/*
Copyright 2019 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// CPU core top module
module tinyriscv(
input wire clk,
input wire rst,
output wire[`MemAddrBus] rib_ex_addr_o,
input wire[`MemBus] rib_ex_data_i,
output wire[`MemBus] rib_ex_data_o,
output wire rib_ex_req_o,
output wire rib_ex_we_o,
output wire[`MemAddrBus] rib_pc_addr_o,
input wire[`MemBus] rib_pc_data_i,
input wire[`RegAddrBus] jtag_reg_addr_i,
input wire[`RegBus] jtag_reg_data_i,
input wire jtag_reg_we_i,
output wire[`RegBus] jtag_reg_data_o,
input wire rib_hold_flag_i,
input wire jtag_halt_flag_i,
input wire jtag_reset_flag_i,
input wire[`INT_BUS] int_i
);
// pc_reg
wire[`InstAddrBus] pc_pc_o;
// if_id
wire[`InstBus] if_inst_o;
wire[`InstAddrBus] if_inst_addr_o;
// id
wire[`RegAddrBus] id_reg1_raddr_o;
wire[`RegAddrBus] id_reg2_raddr_o;
wire id_mem_req_o;
wire[`InstBus] id_inst_o;
wire[`InstAddrBus] id_inst_addr_o;
wire[`RegBus] id_reg1_rdata_o;
wire[`RegBus] id_reg2_rdata_o;
wire id_reg_we_o;
wire[`RegAddrBus] id_reg_waddr_o;
// id_ex
wire[`InstBus] ie_inst_o;
wire[`InstAddrBus] ie_inst_addr_o;
wire ie_reg_we_o;
wire[`RegAddrBus] ie_reg_waddr_o;
wire[`RegBus] ie_reg1_rdata_o;
wire[`RegBus] ie_reg2_rdata_o;
// ex
wire[`MemBus] ex_mem_wdata_o;
wire[`MemAddrBus] ex_mem_raddr_o;
wire[`MemAddrBus] ex_mem_waddr_o;
wire ex_mem_we_o;
wire ex_mem_req_o;
wire[`RegBus] ex_reg_wdata_o;
wire ex_reg_we_o;
wire[`RegAddrBus] ex_reg_waddr_o;
wire ex_hold_flag_o;
wire ex_jump_flag_o;
wire[`InstAddrBus] ex_jump_addr_o;
wire ex_div_start_o;
wire[`RegBus] ex_div_dividend_o;
wire[`RegBus] ex_div_divisor_o;
wire[2:0] ex_div_op_o;
wire[`RegAddrBus] ex_div_reg_waddr_o;
wire[`INT_BUS] ex_int_flag_o;
wire[`InstAddrBus] ex_int_return_addr_o;
wire ex_clint_we_o;
wire[`RegAddrBus] ex_clint_addr_o;
wire[`RegBus] ex_clint_data_o;
// regs
wire[`RegBus] regs_rdata1_o;
wire[`RegBus] regs_rdata2_o;
// ctrl
wire[`Hold_Flag_Bus] ctrl_hold_flag_o;
wire ctrl_jump_flag_o;
wire[`InstAddrBus] ctrl_jump_addr_o;
// div
wire[`DoubleRegBus] div_result_o;
wire div_ready_o;
wire div_busy_o;
wire[2:0] div_op_o;
wire[`RegAddrBus] div_reg_waddr_o;
// clint
wire[`RegBus] clint_data_o;
assign rib_ex_addr_o = (ex_mem_we_o == `WriteEnable)? ex_mem_waddr_o: ex_mem_raddr_o;
assign rib_ex_data_o = ex_mem_wdata_o;
assign rib_ex_req_o = ex_mem_req_o | id_mem_req_o;
assign rib_ex_we_o = ex_mem_we_o;
assign rib_pc_addr_o = pc_pc_o;
pc_reg u_pc_reg(
.clk(clk),
.rst(rst),
.jtag_reset_flag_i(jtag_reset_flag_i),
.pc_o(pc_pc_o),
.hold_flag_i(ctrl_hold_flag_o),
.jump_flag_i(ctrl_jump_flag_o),
.jump_addr_i(ctrl_jump_addr_o)
);
ctrl u_ctrl(
.rst(rst),
.jump_flag_i(ex_jump_flag_o),
.jump_addr_i(ex_jump_addr_o),
.hold_flag_ex_i(ex_hold_flag_o),
.hold_flag_rib_i(rib_hold_flag_i),
.hold_flag_o(ctrl_hold_flag_o),
.int_flag_i(ex_int_flag_o),
.int_return_addr_i(ex_int_return_addr_o),
.jump_flag_o(ctrl_jump_flag_o),
.jump_addr_o(ctrl_jump_addr_o),
.jtag_halt_flag_i(jtag_halt_flag_i)
);
regs u_regs(
.clk(clk),
.rst(rst),
.we_i(ex_reg_we_o),
.waddr_i(ex_reg_waddr_o),
.wdata_i(ex_reg_wdata_o),
.raddr1_i(id_reg1_raddr_o),
.rdata1_o(regs_rdata1_o),
.raddr2_i(id_reg2_raddr_o),
.rdata2_o(regs_rdata2_o),
.jtag_we_i(jtag_reg_we_i),
.jtag_addr_i(jtag_reg_addr_i),
.jtag_data_i(jtag_reg_data_i),
.jtag_data_o(jtag_reg_data_o)
);
if_id u_if_id(
.clk(clk),
.rst(rst),
.inst_i(rib_pc_data_i),
.inst_addr_i(pc_pc_o),
.hold_flag_i(ctrl_hold_flag_o),
.inst_o(if_inst_o),
.inst_addr_o(if_inst_addr_o)
);
id u_id(
.rst(rst),
.inst_i(if_inst_o),
.inst_addr_i(if_inst_addr_o),
.reg1_rdata_i(regs_rdata1_o),
.reg2_rdata_i(regs_rdata2_o),
.ex_jump_flag_i(ex_jump_flag_o),
.ex_int_flag_i(ex_int_flag_o),
.reg1_raddr_o(id_reg1_raddr_o),
.reg2_raddr_o(id_reg2_raddr_o),
.mem_req_o(id_mem_req_o),
.inst_o(id_inst_o),
.inst_addr_o(id_inst_addr_o),
.reg1_rdata_o(id_reg1_rdata_o),
.reg2_rdata_o(id_reg2_rdata_o),
.reg_we_o(id_reg_we_o),
.reg_waddr_o(id_reg_waddr_o)
);
id_ex u_id_ex(
.clk(clk),
.rst(rst),
.inst_i(id_inst_o),
.inst_addr_i(id_inst_addr_o),
.reg_we_i(id_reg_we_o),
.reg_waddr_i(id_reg_waddr_o),
.reg1_rdata_i(id_reg1_rdata_o),
.reg2_rdata_i(id_reg2_rdata_o),
.hold_flag_i(ctrl_hold_flag_o),
.inst_o(ie_inst_o),
.inst_addr_o(ie_inst_addr_o),
.reg_we_o(ie_reg_we_o),
.reg_waddr_o(ie_reg_waddr_o),
.reg1_rdata_o(ie_reg1_rdata_o),
.reg2_rdata_o(ie_reg2_rdata_o)
);
ex u_ex(
.rst(rst),
.inst_i(ie_inst_o),
.inst_addr_i(ie_inst_addr_o),
.reg_we_i(ie_reg_we_o),
.reg_waddr_i(ie_reg_waddr_o),
.reg1_rdata_i(ie_reg1_rdata_o),
.reg2_rdata_i(ie_reg2_rdata_o),
.mem_rdata_i(rib_ex_data_i),
.mem_wdata_o(ex_mem_wdata_o),
.mem_raddr_o(ex_mem_raddr_o),
.mem_waddr_o(ex_mem_waddr_o),
.mem_we_o(ex_mem_we_o),
.mem_req_o(ex_mem_req_o),
.reg_wdata_o(ex_reg_wdata_o),
.reg_we_o(ex_reg_we_o),
.reg_waddr_o(ex_reg_waddr_o),
.clint_we_o(ex_clint_we_o),
.clint_addr_o(ex_clint_addr_o),
.clint_data_o(ex_clint_data_o),
.clint_data_i(clint_data_o),
.int_return_addr_o(ex_int_return_addr_o),
.hold_flag_o(ex_hold_flag_o),
.jump_flag_o(ex_jump_flag_o),
.jump_addr_o(ex_jump_addr_o),
.int_flag_i(int_i),
.int_flag_o(ex_int_flag_o),
.div_ready_i(div_ready_o),
.div_result_i(div_result_o),
.div_busy_i(div_busy_o),
.div_op_i(div_op_o),
.div_reg_waddr_i(div_reg_waddr_o),
.div_start_o(ex_div_start_o),
.div_dividend_o(ex_div_dividend_o),
.div_divisor_o(ex_div_divisor_o),
.div_op_o(ex_div_op_o),
.div_reg_waddr_o(ex_div_reg_waddr_o)
);
div u_div(
.clk(clk),
.rst(rst),
.dividend_i(ex_div_dividend_o),
.divisor_i(ex_div_divisor_o),
.start_i(ex_div_start_o),
.op_i(ex_div_op_o),
.reg_waddr_i(ex_div_reg_waddr_o),
.result_o(div_result_o),
.ready_o(div_ready_o),
.busy_o(div_busy_o),
.op_o(div_op_o),
.reg_waddr_o(div_reg_waddr_o)
);
clint u_clint(
.clk(clk),
.rst(rst),
.we_i(ex_clint_we_o),
.addr_i(ex_clint_addr_o),
.data_i(ex_clint_data_o),
.data_o(clint_data_o)
);
endmodule

View File

@ -1,284 +0,0 @@
/*
Copyright 2019 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
// CPU core top module
module tinyriscv_core (
input wire clk,
input wire rst,
output reg over,
output reg succ,
output wire halt_signal,
input wire jtag_TCK,
input wire jtag_TMS,
input wire jtag_TDI,
output wire jtag_TDO
);
// pc_reg
wire[`SramAddrBus] pc_pc_o;
wire pc_re_o;
// if_id
wire[`SramBus] if_inst_o;
wire[`SramAddrBus] if_inst_addr_o;
// id
wire id_reg1_re_o;
wire[`RegAddrBus] id_reg1_raddr_o;
wire id_reg2_re_o;
wire[`RegAddrBus] id_reg2_raddr_o;
wire[`SramBus] id_inst_o;
wire id_inst_valid_o;
wire id_reg_we_o;
wire[`RegAddrBus] id_reg_waddr_o;
wire id_sram_re_o;
wire id_sram_we_o;
wire[`SramAddrBus] id_pc_o;
wire[`SramAddrBus] id_inst_addr_o;
// ex
wire[`RegBus] ex_reg_wdata_o;
wire[`SramBus] ex_sram_wdata_o;
wire[`SramAddrBus] ex_sram_raddr_o;
wire[`SramAddrBus] ex_sram_waddr_o;
wire ex_jump_flag_o;
wire[`RegBus] ex_jump_addr_o;
wire ex_int_flag_o;
wire[`RegBus] ex_int_addr_o;
wire[`RegBus] ex_div_dividend_o;
wire[`RegBus] ex_div_divisor_o;
wire ex_div_start_o;
wire ex_hold_flag_o;
wire[`RegBus] ex_hold_addr_o;
wire ex_reg_we_o;
wire[`RegAddrBus] ex_reg_waddr_o;
// regs
wire[`RegBus] regs_rdata1_o;
wire[`RegBus] regs_rdata2_o;
// sim_ram
wire[`SramBus] ram_pc_rdata_o;
wire[`SramBus] ram_ex_rdata_o;
wire[`SramBus] ram_dm_rdata_o;
wire ram_we_o;
// div
wire[`DoubleRegBus] div_result_o;
wire div_ready_o;
// timer
wire timer_int_o;
wire[`SramBus] timer_rdata_o;
// jtag
wire jtag_halt_req;
wire jtag_reset_req;
reg jtag_rst;
reg[2:0] jtag_rst_cnt;
wire jtag_mem_we;
wire[31:0] jtag_mem_addr;
wire[31:0] jtag_mem_wdata;
assign halt_signal = jtag_halt_req;
always @ (posedge clk) begin
if (!rst) begin
over <= 1'b1;
succ <= 1'b1;
end else begin
over <= ~u_regs.regs[26]; // when = 1, run over
succ <= ~u_regs.regs[27]; // when = 1, succ
end
end
// jtag module reset logic
always @ (posedge clk) begin
if (rst == `RstEnable) begin
jtag_rst <= 1'b1;
jtag_rst_cnt <= 3'h0;
end else begin
if (jtag_rst_cnt < 3'h5) begin
jtag_rst <= ~jtag_rst;
jtag_rst_cnt <= jtag_rst_cnt + 1'b1;
end else begin
jtag_rst <= 1'b1;
end
end
end
sim_ram u_sim_ram(
.clk(clk),
.rst(rst),
.we_i(id_sram_we_o),
.waddr_i(ex_sram_waddr_o),
.wdata_i(ex_sram_wdata_o),
.dm_we_i(jtag_mem_we),
.dm_addr_i(jtag_mem_addr),
.dm_wdata_i(jtag_mem_wdata),
.dm_rdata_o(ram_dm_rdata_o),
.pc_re_i(pc_re_o),
.pc_raddr_i(pc_pc_o),
.pc_rdata_o(ram_pc_rdata_o),
.ex_re_i(id_sram_re_o),
.ex_raddr_i(ex_sram_raddr_o),
.ex_rdata_o(ram_ex_rdata_o),
.we_o(ram_we_o),
.rdata_i(timer_rdata_o)
);
pc_reg u_pc_reg(
.clk(clk),
.rst(rst),
.pc_o(pc_pc_o),
.re_o(pc_re_o),
.hold_flag_ex_i(ex_hold_flag_o),
.hold_addr_ex_i(ex_hold_addr_o),
.int_flag_ex_i(ex_int_flag_o),
.int_addr_ex_i(ex_int_addr_o),
.dm_halt_req_i(jtag_halt_req),
.dm_reset_req_i(jtag_reset_req),
.jump_flag_ex_i(ex_jump_flag_o),
.jump_addr_ex_i(ex_jump_addr_o)
);
regs u_regs(
.clk(clk),
.rst(rst),
.we(ex_reg_we_o),
.waddr(ex_reg_waddr_o),
.wdata(ex_reg_wdata_o),
.re1(id_reg1_re_o),
.raddr1(id_reg1_raddr_o),
.rdata1(regs_rdata1_o),
.re2(id_reg2_re_o),
.raddr2(id_reg2_raddr_o),
.rdata2(regs_rdata2_o)
);
if_id u_if_id(
.clk(clk),
.rst(rst),
.inst_i(ram_pc_rdata_o),
.inst_addr_i(pc_pc_o),
.inst_o(if_inst_o),
.inst_addr_o(if_inst_addr_o),
.jump_flag_ex_i(ex_jump_flag_o),
.hold_flag_ex_i(ex_hold_flag_o),
.int_flag_ex_i(ex_int_flag_o),
.dm_halt_req_i(jtag_halt_req)
);
id u_id(
.clk(clk),
.rst(rst),
.inst_i(if_inst_o),
.inst_addr_o(id_inst_addr_o),
.inst_addr_i(if_inst_addr_o),
.jump_flag_ex_i(ex_jump_flag_o),
.hold_flag_ex_i(ex_hold_flag_o),
.int_flag_ex_i(ex_int_flag_o),
.halt_flag_dm_i(jtag_halt_req),
.reg1_re_o(id_reg1_re_o),
.reg1_raddr_o(id_reg1_raddr_o),
.reg2_re_o(id_reg2_re_o),
.reg2_raddr_o(id_reg2_raddr_o),
.inst_o(id_inst_o),
.inst_valid_o(id_inst_valid_o),
.reg_we_o(id_reg_we_o),
.reg_waddr_o(id_reg_waddr_o),
.sram_re_o(id_sram_re_o),
.sram_we_o(id_sram_we_o)
);
ex u_ex(
.clk(clk),
.rst(rst),
.inst_i(id_inst_o),
.inst_addr_i(id_inst_addr_o),
.inst_valid_i(id_inst_valid_o),
.reg_we_i(id_reg_we_o),
.reg_waddr_i(id_reg_waddr_o),
.reg1_rdata_i(regs_rdata1_o),
.reg2_rdata_i(regs_rdata2_o),
.reg_wdata_o(ex_reg_wdata_o),
.reg_we_o(ex_reg_we_o),
.reg_waddr_o(ex_reg_waddr_o),
.sram_rdata_i(ram_ex_rdata_o),
.sram_wdata_o(ex_sram_wdata_o),
.sram_raddr_o(ex_sram_raddr_o),
.sram_waddr_o(ex_sram_waddr_o),
.div_dividend_o(ex_div_dividend_o),
.div_divisor_o(ex_div_divisor_o),
.div_ready_i(div_ready_o),
.div_result_i(div_result_o),
.div_start_o(ex_div_start_o),
.hold_flag_o(ex_hold_flag_o),
.hold_addr_o(ex_hold_addr_o),
.jump_flag_o(ex_jump_flag_o),
.jump_addr_o(ex_jump_addr_o),
.int_sig_i(timer_int_o),
.int_flag_o(ex_int_flag_o),
.int_addr_o(ex_int_addr_o)
);
div u_div(
.clk(clk),
.rst(rst),
.dividend_i(ex_div_dividend_o),
.divisor_i(ex_div_divisor_o),
.start_i(ex_div_start_o),
.result_o(div_result_o),
.ready_o(div_ready_o)
);
jtag_top u_jtag_top(
.jtag_rst_n(jtag_rst),
.jtag_pin_TCK(jtag_TCK),
.jtag_pin_TMS(jtag_TMS),
.jtag_pin_TDI(jtag_TDI),
.jtag_pin_TDO(jtag_TDO),
.reg_we(),
.reg_addr(),
.reg_wdata(),
.reg_rdata(),
.mem_we(jtag_mem_we),
.mem_addr(jtag_mem_addr),
.mem_wdata(jtag_mem_wdata),
.mem_rdata(ram_dm_rdata_o),
.halt_req(jtag_halt_req),
.reset_req(jtag_reset_req)
);
timer u_timer(
.clk(clk),
.rst(rst),
.wdata(ex_sram_wdata_o),
.waddr(ex_sram_waddr_o),
.raddr(ex_sram_raddr_o),
.rdata(timer_rdata_o),
.we(ram_we_o),
.int_sig(timer_int_o)
);
endmodule

View File

@ -24,7 +24,7 @@
`define DTM_OP_WRITE 2'b10
module jtag_dm (
module jtag_dm(
clk,
rst_n,
@ -42,6 +42,7 @@ module jtag_dm (
dm_mem_addr,
dm_mem_wdata,
dm_mem_rdata,
dm_op_req,
dm_halt_req,
dm_reset_req
@ -70,6 +71,7 @@ module jtag_dm (
output reg[31:0] dm_mem_addr;
output reg[31:0] dm_mem_wdata;
input wire[31:0] dm_mem_rdata;
output reg dm_op_req;
output reg dm_halt_req;
output reg dm_reset_req;
@ -123,6 +125,7 @@ module jtag_dm (
dm_reg_addr <= 5'h0;
is_halted <= 1'b0;
is_reseted <= 1'b0;
dm_op_req <= 1'b0;
end else begin
if (state == STATE_IDLE) begin
dm_mem_we <= 1'b0;
@ -134,6 +137,9 @@ module jtag_dm (
address <= dtm_req_data[DTM_REQ_BITS - 1:DMI_DATA_BITS + DMI_OP_BITS];
req_data <= dtm_req_data;
dm_is_busy <= 1'b1;
dm_op_req <= 1'b1;
end else begin
dm_op_req <= 1'b0;
end
end else begin
case (op)
@ -204,7 +210,7 @@ module jtag_dm (
dmstatus <= 32'h400982; // not halted, all running
hartinfo <= 32'h0;
sbcs <= 32'h20040404;
abstractcs <=32'h1000003;
abstractcs <= 32'h1000003;
dmcontrol <= data;
dm_halt_req <= 1'b0;
dm_reset_req <= 1'b0;

View File

@ -20,7 +20,7 @@
`define DTM_REQ_INVALID 1'b0
module jtag_driver (
module jtag_driver(
rst_n,

View File

@ -15,7 +15,7 @@
*/
module jtag_top (
module jtag_top(
input wire jtag_rst_n,
@ -24,17 +24,18 @@ module jtag_top (
input wire jtag_pin_TDI,
output wire jtag_pin_TDO,
output wire reg_we,
output wire[4:0] reg_addr,
output wire[31:0] reg_wdata,
input wire[31:0] reg_rdata,
output wire mem_we,
output wire[31:0] mem_addr,
output wire[31:0] mem_wdata,
input wire[31:0] mem_rdata,
output wire reg_we_o,
output wire[4:0] reg_addr_o,
output wire[31:0] reg_wdata_o,
input wire[31:0] reg_rdata_i,
output wire mem_we_o,
output wire[31:0] mem_addr_o,
output wire[31:0] mem_wdata_o,
input wire[31:0] mem_rdata_i,
output wire op_req_o,
output wire halt_req,
output wire reset_req
output wire halt_req_o,
output wire reset_req_o
);
@ -53,7 +54,7 @@ module jtag_top (
wire[DM_RESP_BITS - 1:0] dm_resp_data;
jtag_driver u_jtag_driver (
jtag_driver u_jtag_driver(
.rst_n(jtag_rst_n),
.jtag_TCK(jtag_pin_TCK),
.jtag_TDI(jtag_pin_TDI),
@ -65,23 +66,24 @@ module jtag_top (
.dtm_req_data(dtm_req_data)
);
jtag_dm u_jtag_dm (
jtag_dm u_jtag_dm(
.clk(jtag_pin_TCK),
.rst_n(jtag_rst_n),
.dtm_req_valid(dtm_req_valid),
.dtm_req_data(dtm_req_data),
.dm_is_busy(dm_is_busy),
.dm_resp_data(dm_resp_data),
.dm_reg_we(reg_we),
.dm_reg_addr(reg_addr),
.dm_reg_wdata(reg_wdata),
.dm_reg_rdata(reg_rdata),
.dm_mem_we(mem_we),
.dm_mem_addr(mem_addr),
.dm_mem_wdata(mem_wdata),
.dm_mem_rdata(mem_rdata),
.dm_halt_req(halt_req),
.dm_reset_req(reset_req)
.dm_reg_we(reg_we_o),
.dm_reg_addr(reg_addr_o),
.dm_reg_wdata(reg_wdata_o),
.dm_reg_rdata(reg_rdata_i),
.dm_mem_we(mem_we_o),
.dm_mem_addr(mem_addr_o),
.dm_mem_wdata(mem_wdata_o),
.dm_mem_rdata(mem_rdata_i),
.dm_op_req(op_req_o),
.dm_halt_req(halt_req_o),
.dm_reset_req(reset_req_o)
);
endmodule

View File

@ -14,63 +14,72 @@
limitations under the License.
*/
`include "defines.v"
// 32 bits count up timer module
module timer (
module timer(
input wire clk,
input wire rst,
input wire[31:0] wdata,
input wire[31:0] waddr,
input wire[31:0] raddr,
input wire we,
input wire[31:0] data_i,
input wire[31:0] addr_i,
input wire we_i,
input wire req_i,
output reg[31:0] rdata,
output wire int_sig
output reg[31:0] data_o,
output wire int_sig_o,
output reg ack_o
);
// timer expired value
// addr: 0x10000008
reg[31:0] timer_value;
// timer current count, read only
// addr: 0x10000004
reg[31:0] timer_count;
localparam ctrl_reg = 32'h00;
localparam count_reg = 32'h04;
localparam value_reg = 32'h08;
// [0]: timer enable
// [1]: timer int enable
// [2]: timer int pending, write 1 to clear it
// addr: 0x10000000
// addr offset: 0x00
reg[31:0] timer_ctrl;
// timer current count, read only
// addr offset: 0x04
reg[31:0] timer_count;
// timer expired value
// addr offset: 0x08
reg[31:0] timer_value;
assign int_sig_o = ((timer_ctrl[0] == 1'b1) && (timer_ctrl[1] == 1'b1) && (timer_ctrl[2] == 1'b1)) ? `INT_ASSERT : `INT_DEASSERT;
assign int_sig = ((timer_ctrl[0] == 1'b1) && (timer_ctrl[1] == 1'b1) && (timer_ctrl[2] == 1'b1)) ? 1'b1 : 1'b0;
// write timer regs
always @ (posedge clk) begin
if (rst == 1'b0) begin
timer_count <= 32'h0;
timer_value <= 32'h0;
timer_ctrl <= 32'h0;
if (rst == `RstEnable) begin
timer_count <= `ZeroWord;
timer_value <= `ZeroWord;
timer_ctrl <= `ZeroWord;
ack_o <= `RIB_ACK;
end else begin
if (timer_ctrl[0] == 1'b1) begin
timer_count <= timer_count + 1'b1;
if (timer_count == timer_value) begin
timer_ctrl[2] <= 1'b1;
timer_count <= 32'h0;
timer_count <= `ZeroWord;
end
end
if (we == 1'b1) begin
if (waddr == 32'h10000008) begin
timer_value <= wdata;
end else if (waddr == 32'h10000000) begin
if (wdata[2] == 1'b0) begin
timer_ctrl <= wdata;
if (we_i == `WriteEnable) begin
if (addr_i == value_reg) begin
timer_value <= data_i;
end else if (addr_i == ctrl_reg) begin
if (data_i[2] == 1'b0) begin
timer_ctrl <= {data_i[31:3], timer_ctrl[2], data_i[1:0]};
// write 1 to clear pending
end else begin
timer_ctrl <= {wdata[31:3], 1'b0, wdata[1:0]};
timer_ctrl <= {data_i[31:3], 1'b0, data_i[1:0]};
end
end
end
@ -79,18 +88,23 @@ module timer (
// read timer regs
always @ (*) begin
if (rst == 1'b0) begin
rdata <= 32'h0;
if (rst == `RstEnable) begin
data_o <= `ZeroWord;
end else begin
if (raddr == 32'h10000008) begin
rdata <= timer_value;
end else if (raddr == 32'h10000000) begin
rdata <= timer_ctrl;
end else if (raddr == 32'h10000004) begin
rdata <= timer_count;
end else begin
rdata <= 32'h0;
end
case (addr_i)
value_reg: begin
data_o <= timer_value;
end
ctrl_reg: begin
data_o <= timer_ctrl;
end
count_reg: begin
data_o <= timer_count;
end
default: begin
data_o <= `ZeroWord;
end
endcase
end
end

270
rtl/soc/tinyriscv_soc_top.v Normal file
View File

@ -0,0 +1,270 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the 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 "defines.v"
module tinyriscv_soc_top(
input wire clk,
input wire rst,
output reg over,
output reg succ,
output wire halted_ind,
input wire jtag_TCK,
input wire jtag_TMS,
input wire jtag_TDI,
output wire jtag_TDO
);
// master 0 interface
wire[`MemAddrBus] m0_addr_i;
wire[`MemBus] m0_data_i;
wire[`MemBus] m0_data_o;
wire m0_ack_o;
wire m0_req_i;
wire m0_we_i;
// master 1 interface
wire[`MemAddrBus] m1_addr_i;
wire[`MemBus] m1_data_i;
wire[`MemBus] m1_data_o;
wire m1_ack_o;
wire m1_req_i;
wire m1_we_i;
// master 2 interface
wire[`MemAddrBus] m2_addr_i;
wire[`MemBus] m2_data_i;
wire[`MemBus] m2_data_o;
wire m2_ack_o;
wire m2_req_i;
wire m2_we_i;
// slave 0 interface
wire[`MemAddrBus] s0_addr_o;
wire[`MemBus] s0_data_o;
wire[`MemBus] s0_data_i;
wire s0_ack_i;
wire s0_req_o;
wire s0_we_o;
// slave 1 interface
wire[`MemAddrBus] s1_addr_o;
wire[`MemBus] s1_data_o;
wire[`MemBus] s1_data_i;
wire s1_ack_i;
wire s1_req_o;
wire s1_we_o;
// slave 2 interface
wire[`MemAddrBus] s2_addr_o;
wire[`MemBus] s2_data_o;
wire[`MemBus] s2_data_i;
wire s2_ack_i;
wire s2_req_o;
wire s2_we_o;
// rib
wire rib_hold_flag_o;
// jtag
wire jtag_halt_req_o;
wire jtag_reset_req_o;
reg jtag_rst;
reg[2:0] jtag_rst_cnt;
wire[`RegAddrBus] jtag_reg_addr_o;
wire[`RegBus] jtag_reg_data_o;
wire jtag_reg_we_o;
wire[`RegBus] jtag_reg_data_i;
// tinyriscv
wire[`INT_BUS] int_flag;
// timer0
wire timer0_int;
assign int_flag = {7'h0, timer0_int};
assign halted_ind = ~jtag_halt_req_o;
always @ (posedge clk) begin
if (rst == `RstEnable) begin
over <= 1'b1;
succ <= 1'b1;
end else begin
over <= ~u_tinyriscv.u_regs.regs[26]; // when = 1, run over
succ <= ~u_tinyriscv.u_regs.regs[27]; // when = 1, succ
end
end
tinyriscv u_tinyriscv(
.clk(clk),
.rst(rst),
.rib_ex_addr_o(m0_addr_i),
.rib_ex_data_i(m0_data_o),
.rib_ex_data_o(m0_data_i),
.rib_ex_req_o(m0_req_i),
.rib_ex_we_o(m0_we_i),
.rib_pc_addr_o(m1_addr_i),
.rib_pc_data_i(m1_data_o),
.jtag_reg_addr_i(jtag_reg_addr_o),
.jtag_reg_data_i(jtag_reg_data_o),
.jtag_reg_we_i(jtag_reg_we_o),
.jtag_reg_data_o(jtag_reg_data_i),
.rib_hold_flag_i(rib_hold_flag_o),
.jtag_halt_flag_i(jtag_halt_req_o),
.jtag_reset_flag_i(jtag_reset_req_o),
.int_i(int_flag)
);
rom u_rom(
.clk(clk),
.rst(rst),
.we_i(s0_we_o),
.addr_i(s0_addr_o),
.data_i(s0_data_o),
.req_i(s0_req_o),
.data_o(s0_data_i),
.ack_o(s0_ack_i)
);
ram u_ram(
.clk(clk),
.rst(rst),
.we_i(s1_we_o),
.addr_i(s1_addr_o),
.data_i(s1_data_o),
.req_i(s1_req_o),
.data_o(s1_data_i),
.ack_o(s1_ack_i)
);
timer timer_0(
.clk(clk),
.rst(rst),
.data_i(s2_data_o),
.addr_i(s2_addr_o),
.we_i(s2_we_o),
.data_o(s2_data_i),
.int_sig_o(timer0_int),
.req_i(s2_req_o),
.ack_o(s2_ack_i)
);
rib u_rib(
.clk(clk),
.rst(rst),
// master 0 interface
.m0_addr_i(m0_addr_i),
.m0_data_i(m0_data_i),
.m0_data_o(m0_data_o),
.m0_ack_o(m0_ack_o),
.m0_req_i(m0_req_i),
.m0_we_i(m0_we_i),
// master 1 interface
.m1_addr_i(m1_addr_i),
.m1_data_i(`ZeroWord),
.m1_data_o(m1_data_o),
.m1_ack_o(m1_ack_o),
.m1_req_i(`RIB_REQ),
.m1_we_i(`WriteDisable),
// master 2 interface
.m2_addr_i(m2_addr_i),
.m2_data_i(m2_data_i),
.m2_data_o(m2_data_o),
.m2_ack_o(m2_ack_o),
.m2_req_i(m2_req_i),
.m2_we_i(m2_we_i),
// slave 0 interface
.s0_addr_o(s0_addr_o),
.s0_data_o(s0_data_o),
.s0_data_i(s0_data_i),
.s0_ack_i(s0_ack_i),
.s0_req_o(s0_req_o),
.s0_we_o(s0_we_o),
// slave 1 interface
.s1_addr_o(s1_addr_o),
.s1_data_o(s1_data_o),
.s1_data_i(s1_data_i),
.s1_ack_i(s1_ack_i),
.s1_req_o(s1_req_o),
.s1_we_o(s1_we_o),
// slave 2 interface
.s2_addr_o(s2_addr_o),
.s2_data_o(s2_data_o),
.s2_data_i(s2_data_i),
.s2_ack_i(s2_ack_i),
.s2_req_o(s2_req_o),
.s2_we_o(s2_we_o),
.hold_flag_o(rib_hold_flag_o)
);
// jtag module reset logic
always @ (posedge clk) begin
if (rst == `RstEnable) begin
jtag_rst <= 1'b1;
jtag_rst_cnt <= 3'h0;
end else begin
if (jtag_rst_cnt < 3'h5) begin
jtag_rst <= ~jtag_rst;
jtag_rst_cnt <= jtag_rst_cnt + 1'b1;
end else begin
jtag_rst <= 1'b1;
end
end
end
jtag_top u_jtag_top(
.jtag_rst_n(jtag_rst),
.jtag_pin_TCK(jtag_TCK),
.jtag_pin_TMS(jtag_TMS),
.jtag_pin_TDI(jtag_TDI),
.jtag_pin_TDO(jtag_TDO),
.reg_we_o(jtag_reg_we_o),
.reg_addr_o(jtag_reg_addr_o),
.reg_wdata_o(jtag_reg_data_o),
.reg_rdata_i(jtag_reg_data_i),
.mem_we_o(m2_we_i),
.mem_addr_o(m2_addr_i),
.mem_wdata_o(m2_data_i),
.mem_rdata_i(m2_data_o),
.op_req_o(m2_req_i),
.halt_req_o(jtag_halt_req_o),
.reset_req_o(jtag_reset_req_o)
);
endmodule

View File

@ -1,354 +1,155 @@
0080006f
06c0006f
10000197
7f818193
00018113
00000d13
00000d93
00000093
00000113
00208f33
00000e93
00200193
4ddf1663
00100093
00100113
00208f33
00200e93
00300193
4bdf1a63
00300093
00700113
00208f33
00a00e93
00400193
49df1e63
00000093
ffff8137
00208f33
ffff8eb7
00500193
49df1263
800000b7
00000113
00208f33
80000eb7
00600193
47df1663
800000b7
ffff8137
00208f33
7fff8eb7
00700193
45df1a63
00000093
00008137
fff10113
00208f33
00008eb7
fffe8e93
00800193
43df1a63
800000b7
fff08093
00000113
00208f33
80000eb7
fffe8e93
00900193
41df1a63
800000b7
fff08093
00008137
fff10113
00208f33
80008eb7
ffee8e93
00a00193
3fdf1863
800000b7
00008137
fff10113
00208f33
80008eb7
fffe8e93
00b00193
3ddf1863
800000b7
fff08093
ffff8137
00208f33
7fff8eb7
fffe8e93
00c00193
3bdf1863
00000093
fff00113
00208f33
fff00e93
00d00193
39df1c63
fff00093
00100113
00208f33
00000e93
00e00193
39df1063
fff00093
fff00113
00208f33
ffe00e93
00f00193
37df1463
00100093
80000137
fff10113
00208f33
80000eb7
01000193
35df1663
00d00093
00b00113
002080b3
01800e93
01100193
33d09a63
00e00093
00b00113
00208133
01900e93
01200193
31d11e63
00d00093
001080b3
01a00e93
01300193
31d09463
00000213
00d00093
00b00113
00208f33
000f0313
00120213
00200293
fe5214e3
01800e93
01400193
2dd31e63
00000213
00e00093
00b00113
00208f33
00000013
000f0313
00120213
00200293
fe5212e3
01900e93
01500193
2bd31663
00000213
00f00093
00b00113
00208f33
00000013
00000013
000f0313
00120213
00200293
fe5210e3
01a00e93
01600193
27d31c63
00000213
00d00093
00b00113
00208f33
00120213
00200293
fe5216e3
01800e93
01700193
25df1863
00000213
00e00093
00b00113
00000013
00208f33
00120213
00200293
fe5214e3
01900e93
01800193
23df1263
00000213
00f00093
00b00113
00000013
00000013
00208f33
00120213
00200293
fe5212e3
01a00e93
01900193
1fdf1a63
00000213
00d00093
00000013
00b00113
00208f33
00120213
00200293
fe5214e3
01800e93
01a00193
1ddf1463
00000213
00e00093
00000013
00b00113
00000013
00208f33
00120213
00200293
fe5212e3
01900e93
01b00193
19df1c63
00000213
00f00093
00000013
00000013
00b00113
00208f33
00120213
00200293
fe5212e3
01a00e93
01c00193
17df1463
00000213
00b00113
00d00093
00208f33
00120213
00200293
fe5216e3
01800e93
01d00193
15df1063
00000213
00b00113
00e00093
00000013
00208f33
00120213
00200293
fe5214e3
01900e93
01e00193
11df1a63
00000213
00b00113
00f00093
00000013
00000013
00208f33
00120213
00200293
fe5212e3
01a00e93
01f00193
0fdf1263
00000213
00b00113
00000013
00d00093
00208f33
00120213
00200293
fe5214e3
01800e93
02000193
0bdf1c63
00000213
00b00113
00000013
00e00093
00000013
00208f33
00120213
00200293
fe5212e3
01900e93
02100193
09df1463
00000213
00b00113
00000013
00000013
00f00093
00208f33
00120213
00200293
fe5212e3
01a00e93
02200193
05df1c63
00f00093
00100133
00f00e93
02300193
05d11263
02000093
00008133
02000e93
02400193
03d11863
000000b3
00000e93
02500193
03d09063
01000093
01e00113
00208033
00000e93
02600193
01d01463
00301863
26c00513
10000597
fe058593
10000617
fd860613
00c5fc63
00052283
0055a023
00450513
00458593
fec5e8e3
10000517
fb850513
80818593
00b57863
00052023
00450513
feb56ce3
144000ef
00100d13
00000d93
0000006f
00100d13
f8010113
00112223
00212423
00312623
00412823
00512a23
00612c23
00712e23
02812023
02912223
02a12423
02b12623
02c12823
02d12a23
02e12c23
02f12e23
05012023
05112223
05212423
05312623
05412823
05512a23
05612c23
05712e23
07812023
07912223
07c12823
07d12a23
07e12c23
07f12e23
140000ef
00412083
00812103
00c12183
01012203
01412283
01812303
01c12383
02012403
02412483
02812503
02c12583
03012603
03412683
03812703
03c12783
04012803
04412883
04812903
04c12983
05012a03
05412a83
05812b03
05c12b83
06012c03
06412c83
07012e03
07412e83
07812f03
07c12f83
08010113
30200073
ff010113
00812623
01010413
00100d93
0000006f
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000013
00c12403
01010113
00008067
ff010113
00812623
01010413
00000d93
00000013
00c12403
01010113
00008067
ff010113
00112623
00812423
01010413
10000797
e4878793
0007a023
200007b7
00878793
1f400713
00e7a023
200007b7
00700713
00e7a023
10000797
e2078793
0007a703
00a00793
fef718e3
200007b7
0007a023
10000797
e0478793
0007a023
f61ff0ef
00000013
00000793
00078513
00c12083
00812403
01010113
00008067
ff010113
00812623
01010413
200007b7
00700713
00e7a023
10000797
dc078793
0007a783
00178713
10000797
db078793
00e7a023
00000013
00c12403
01010113
00008067

21328
sim/out.vvp

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
iverilog -s tinyriscv_core_tb -o out.vvp -I ..\rtl\core tinyriscv_core_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv_core.v ..\rtl\core\pc_reg.v ..\rtl\core\regs.v ..\rtl\core\sim_ram.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\core\ram.v ..\rtl\core\rom.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\soc\tinyriscv_soc_top.v
vvp out.vvp

View File

@ -1,3 +1,3 @@
..\tools\BinToMem_CLI.exe %1 %2
iverilog -s tinyriscv_core_tb -o out.vvp -I ..\rtl\core tinyriscv_core_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv_core.v ..\rtl\core\pc_reg.v ..\rtl\core\regs.v ..\rtl\core\sim_ram.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\core\ram.v ..\rtl\core\rom.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\soc\tinyriscv_soc_top.v
vvp out.vvp

36
sim/test_all_isa.py Normal file
View File

@ -0,0 +1,36 @@
import os
# 找出path目录下的所有bin文件
def list_binfiles(path):
files = []
list_dir = os.walk(path)
for maindir, subdir, all_file in list_dir:
for filename in all_file:
apath = os.path.join(maindir, filename)
if apath.endswith('.bin'):
files.append(apath)
return files
files = list_binfiles('..\\tests\\isa\\generated')
anyfail = False
# 对每一个bin文件进行测试
for file in files:
#print(file)
cmd = '.\\sim_new_nowave.bat ' + file + ' inst.data'
f = os.popen(cmd)
r = f.read()
f.close()
if (r.find('TEST_PASS') != -1):
print(file + ' PASS')
else:
print(file + ' !!!FAIL!!!')
anyfail = True
break
if (anyfail == False):
print('Congratulation, All PASS...')

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
// testbench module
module tinyriscv_core_tb;
module tinyriscv_soc_tb;
reg clk;
reg rst;
@ -16,9 +16,9 @@ module tinyriscv_core_tb;
always #10 clk = ~clk; // 50MHz
wire[`RegBus] x3 = u_tinyriscv_core.u_regs.regs[3];
wire[`RegBus] x26 = u_tinyriscv_core.u_regs.regs[26];
wire[`RegBus] x27 = u_tinyriscv_core.u_regs.regs[27];
wire[`RegBus] x3 = tinyriscv_soc_top_0.u_tinyriscv.u_regs.regs[3];
wire[`RegBus] x26 = tinyriscv_soc_top_0.u_tinyriscv.u_regs.regs[26];
wire[`RegBus] x27 = tinyriscv_soc_top_0.u_tinyriscv.u_regs.regs[27];
integer r;
@ -31,10 +31,10 @@ module tinyriscv_core_tb;
integer i;
reg[39:0] shift_reg;
reg in;
wire[39:0] req_data = u_tinyriscv_core.u_jtag_top.u_jtag_driver.dtm_req_data;
wire[4:0] ir_reg = u_tinyriscv_core.u_jtag_top.u_jtag_driver.ir_reg;
wire dtm_req_valid = u_tinyriscv_core.u_jtag_top.u_jtag_driver.dtm_req_valid;
wire[31:0] dmstatus = u_tinyriscv_core.u_jtag_top.u_jtag_dm.dmstatus;
wire[39:0] req_data = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_data;
wire[4:0] ir_reg = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.ir_reg;
wire dtm_req_valid = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_valid;
wire[31:0] dmstatus = tinyriscv_soc_top_0.u_jtag_top.u_jtag_dm.dmstatus;
`endif
initial begin
@ -75,7 +75,7 @@ module tinyriscv_core_tb;
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
$display("fail testnum = %2d", x3);
for (r = 0; r < 32; r++)
$display("x%2d = 0x%x", r, u_tinyriscv_core.u_regs.regs[r]);
$display("x%2d = 0x%x", r, tinyriscv_soc_top_0.u_tinyriscv.u_regs.regs[r]);
end
`endif
@ -485,22 +485,22 @@ module tinyriscv_core_tb;
// read mem data
initial begin
$readmemh ("inst.data", u_tinyriscv_core.u_sim_ram.rom);
$readmemh ("inst.data", tinyriscv_soc_top_0.u_rom._rom);
end
// generate wave file, used by gtkwave
initial begin
$dumpfile("tinyriscv_core_tb.vcd");
$dumpvars(0, tinyriscv_core_tb);
$dumpfile("tinyriscv_soc_tb.vcd");
$dumpvars(0, tinyriscv_soc_tb);
end
tinyriscv_core u_tinyriscv_core (
tinyriscv_soc_top tinyriscv_soc_top_0(
.clk(clk),
.rst(rst),
.rst(rst)/*
.jtag_TCK(TCK),
.jtag_TMS(TMS),
.jtag_TDI(TDI),
.jtag_TDO(TDO)
.jtag_TDO(TDO)*/
);
endmodule

428947
sim/tinyriscv_soc_tb.vcd Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
RISCV_ARCH := rv32i
RISCV_ARCH := rv32im
RISCV_ABI := ilp32
RISCV_PATH := ../../../tools/gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64/

View File

@ -1 +1 @@
Simple c program which add from 1 to 100.
加减乘除运算例程。

View File

@ -1,25 +1,147 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY
{
flash (wxa!ri) : ORIGIN = 0x00000000, LENGTH = 4K
ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 2K
}
SECTIONS
{
__stack_size = 0x100;
__stack_size = DEFINED(__stack_size) ? __stack_size : 1K;
. = 0x00000000;
.text : { *(.text) }
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
PROVIDE( _data_start = . );
.data ALIGN(0x1000) : { *(.data) }
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_end = . );
PROVIDE( _data_lma = . );
} >flash AT>flash
PROVIDE( _bss_start = . );
.bss : { *(.bss) }
PROVIDE( _bss_end = . );
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
PROVIDE(_stack_begin = .);
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
PROVIDE(_stack_end = .);
_end = .;
} >ram AT>ram
}

View File

@ -9,18 +9,35 @@ static void set_test_fail()
asm("li x27, 0x00");
}
// add 1 to 100
int mul = 3;
int div = 3;
int main()
{
int i;
int sum;
mul = 6;
//div = 3;
sum = 0;
// sum = 5050
for (i = 0; i <= 100; i++)
sum += i;
if (sum == 5050)
// sum = 3775
for (i = 0; i <= 50; i++)
sum -= i;
// sum = 22650
sum = sum * mul;
// sum = 7550
sum = sum / div;
if (sum == 7550)
set_test_pass();
else
set_test_fail();

Binary file not shown.

Binary file not shown.

View File

@ -2,78 +2,133 @@
simple: file format elf32-littleriscv
Disassembly of section .text:
Disassembly of section .init:
00000000 <_start>:
0: 0080006f j 8 <_reset_handler>
4: 01c0006f j 20 <_timer_handler>
0: 0040006f j 4 <_reset_handler>
00000008 <_reset_handler>:
8: 10000113 li sp,256
c: 00000d13 li s10,0
10: 00000d93 li s11,0
14: 058000ef jal ra,6c <main>
18: 00100d13 li s10,1
00000004 <_reset_handler>:
4: 10000197 auipc gp,0x10000
8: 7fc18193 addi gp,gp,2044 # 10000800 <__global_pointer$>
c: 00018113 mv sp,gp
10: 00000d13 li s10,0
14: 00000d93 li s11,0
18: 18c00513 li a0,396
1c: 10000597 auipc a1,0x10000
20: fe458593 addi a1,a1,-28 # 10000000 <_data>
24: 80818613 addi a2,gp,-2040 # 10000008 <__bss_start>
28: 00c5fc63 bgeu a1,a2,40 <_reset_handler+0x3c>
2c: 00052283 lw t0,0(a0)
30: 0055a023 sw t0,0(a1)
34: 00450513 addi a0,a0,4
38: 00458593 addi a1,a1,4
3c: fec5e8e3 bltu a1,a2,2c <_reset_handler+0x28>
40: 80818513 addi a0,gp,-2040 # 10000008 <__bss_start>
44: 80818593 addi a1,gp,-2040 # 10000008 <__bss_start>
48: 00b57863 bgeu a0,a1,58 <_reset_handler+0x54>
4c: 00052023 sw zero,0(a0)
50: 00450513 addi a0,a0,4
54: feb56ce3 bltu a0,a1,4c <_reset_handler+0x48>
58: 04c000ef jal ra,a4 <main>
5c: 00100d13 li s10,1
0000001c <loop>:
1c: 0000006f j 1c <loop>
00000060 <loop>:
60: 0000006f j 60 <loop>
00000020 <_timer_handler>:
20: 00000097 auipc ra,0x0
24: 000000e7 jalr zero # 0 <_start>
28: 00008067 ret
Disassembly of section .text:
0000002c <set_test_pass>:
2c: ff010113 addi sp,sp,-16
30: 00812623 sw s0,12(sp)
34: 01010413 addi s0,sp,16
38: 00100d93 li s11,1
3c: 00000013 nop
40: 00c12403 lw s0,12(sp)
44: 01010113 addi sp,sp,16
48: 00008067 ret
00000064 <set_test_pass>:
64: ff010113 addi sp,sp,-16
68: 00812623 sw s0,12(sp)
6c: 01010413 addi s0,sp,16
70: 00100d93 li s11,1
74: 00000013 nop
78: 00c12403 lw s0,12(sp)
7c: 01010113 addi sp,sp,16
80: 00008067 ret
0000004c <set_test_fail>:
4c: ff010113 addi sp,sp,-16
50: 00812623 sw s0,12(sp)
54: 01010413 addi s0,sp,16
58: 00000d93 li s11,0
5c: 00000013 nop
60: 00c12403 lw s0,12(sp)
64: 01010113 addi sp,sp,16
68: 00008067 ret
00000084 <set_test_fail>:
84: ff010113 addi sp,sp,-16
88: 00812623 sw s0,12(sp)
8c: 01010413 addi s0,sp,16
90: 00000d93 li s11,0
94: 00000013 nop
98: 00c12403 lw s0,12(sp)
9c: 01010113 addi sp,sp,16
a0: 00008067 ret
0000006c <main>:
6c: fe010113 addi sp,sp,-32
70: 00112e23 sw ra,28(sp)
74: 00812c23 sw s0,24(sp)
78: 02010413 addi s0,sp,32
7c: fe042423 sw zero,-24(s0)
80: fe042623 sw zero,-20(s0)
84: 0200006f j a4 <main+0x38>
88: fe842703 lw a4,-24(s0)
8c: fec42783 lw a5,-20(s0)
90: 00f707b3 add a5,a4,a5
94: fef42423 sw a5,-24(s0)
98: fec42783 lw a5,-20(s0)
9c: 00178793 addi a5,a5,1
a0: fef42623 sw a5,-20(s0)
a4: fec42703 lw a4,-20(s0)
a8: 06400793 li a5,100
ac: fce7dee3 bge a5,a4,88 <main+0x1c>
b0: fe842703 lw a4,-24(s0)
b4: 000017b7 lui a5,0x1
b8: 3ba78793 addi a5,a5,954 # 13ba <_end+0x12ba>
bc: 00f71663 bne a4,a5,c8 <main+0x5c>
c0: f6dff0ef jal ra,2c <set_test_pass>
c4: 0080006f j cc <main+0x60>
c8: f85ff0ef jal ra,4c <set_test_fail>
cc: 00000793 li a5,0
d0: 00078513 mv a0,a5
d4: 01c12083 lw ra,28(sp)
d8: 01812403 lw s0,24(sp)
dc: 02010113 addi sp,sp,32
e0: 00008067 ret
000000a4 <main>:
a4: fe010113 addi sp,sp,-32
a8: 00112e23 sw ra,28(sp)
ac: 00812c23 sw s0,24(sp)
b0: 02010413 addi s0,sp,32
b4: 10000797 auipc a5,0x10000
b8: f4c78793 addi a5,a5,-180 # 10000000 <_data>
bc: 00600713 li a4,6
c0: 00e7a023 sw a4,0(a5)
c4: fe042423 sw zero,-24(s0)
c8: fe042623 sw zero,-20(s0)
cc: 0200006f j ec <main+0x48>
d0: fe842703 lw a4,-24(s0)
d4: fec42783 lw a5,-20(s0)
d8: 00f707b3 add a5,a4,a5
dc: fef42423 sw a5,-24(s0)
e0: fec42783 lw a5,-20(s0)
e4: 00178793 addi a5,a5,1
e8: fef42623 sw a5,-20(s0)
ec: fec42703 lw a4,-20(s0)
f0: 06400793 li a5,100
f4: fce7dee3 bge a5,a4,d0 <main+0x2c>
f8: fe042623 sw zero,-20(s0)
fc: 0200006f j 11c <main+0x78>
100: fe842703 lw a4,-24(s0)
104: fec42783 lw a5,-20(s0)
108: 40f707b3 sub a5,a4,a5
10c: fef42423 sw a5,-24(s0)
110: fec42783 lw a5,-20(s0)
114: 00178793 addi a5,a5,1
118: fef42623 sw a5,-20(s0)
11c: fec42703 lw a4,-20(s0)
120: 03200793 li a5,50
124: fce7dee3 bge a5,a4,100 <main+0x5c>
128: 10000797 auipc a5,0x10000
12c: ed878793 addi a5,a5,-296 # 10000000 <_data>
130: 0007a783 lw a5,0(a5)
134: fe842703 lw a4,-24(s0)
138: 02f707b3 mul a5,a4,a5
13c: fef42423 sw a5,-24(s0)
140: 10000797 auipc a5,0x10000
144: ec478793 addi a5,a5,-316 # 10000004 <div>
148: 0007a783 lw a5,0(a5)
14c: fe842703 lw a4,-24(s0)
150: 02f747b3 div a5,a4,a5
154: fef42423 sw a5,-24(s0)
158: fe842703 lw a4,-24(s0)
15c: 000027b7 lui a5,0x2
160: d7e78793 addi a5,a5,-642 # 1d7e <__stack_size+0x197e>
164: 00f71663 bne a4,a5,170 <main+0xcc>
168: efdff0ef jal ra,64 <set_test_pass>
16c: 0080006f j 174 <main+0xd0>
170: f15ff0ef jal ra,84 <set_test_fail>
174: 00000793 li a5,0
178: 00078513 mv a0,a5
17c: 01c12083 lw ra,28(sp)
180: 01812403 lw s0,24(sp)
184: 02010113 addi sp,sp,32
188: 00008067 ret
Disassembly of section .data:
10000000 <mul>:
10000000: 00000003 lb zero,0(zero) # 0 <_start>
10000004 <div>:
10000004: 00000003 lb zero,0(zero) # 0 <_start>
Disassembly of section .stack:
10000400 <_sp-0x400>:
...
Disassembly of section .comment:
@ -82,11 +137,11 @@ Disassembly of section .comment:
4: 2820 fld fs0,80(s0)
6: 20554e47 fmsub.s ft8,fa0,ft5,ft4,rmm
a: 434d li t1,19
c: 2055 jal b0 <main+0x44>
c: 2055 jal b0 <main+0xc>
e: 6345 lui t1,0x11
10: 696c flw fa1,84(a0)
12: 7370 flw fa2,100(a4)
14: 2065 jal bc <main+0x50>
14: 2065 jal bc <main+0x18>
16: 4952 lw s2,20(sp)
18: 562d4353 0x562d4353
1c: 4520 lw s0,72(a0)

View File

@ -1,26 +1,46 @@
.section .text;
.align 2;
.section .init;
.globl _start;
.weak TIMER_IRQHandler
.type _start,@function
_start:
j _reset_handler
j _timer_handler
_reset_handler:
la sp, _sp
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _sp
li x26, 0x00
li x27, 0x00
/* Load data section */
la a0, _data_lma
la a1, _data
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, __bss_start
la a1, _end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
call main
li x26, 0x01
loop:
j loop
_timer_handler:
call TIMER_IRQHandler
ret

View File

@ -1,5 +1,5 @@
RISCV_ARCH := rv32i
RISCV_ARCH := rv32im
RISCV_ABI := ilp32
RISCV_PATH := ../../../tools/gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64/

View File

@ -1 +1 @@
Simple c program which can verify interrupt function.
定时器中断例程。

View File

@ -1,25 +1,147 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY
{
flash (wxa!ri) : ORIGIN = 0x00000000, LENGTH = 4K
ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 2K
}
SECTIONS
{
__stack_size = 0x1000;
__stack_size = DEFINED(__stack_size) ? __stack_size : 1K;
. = 0x00000000;
.text : { *(.text) }
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
PROVIDE( _data_start = . );
.data ALIGN(0x1000) : { *(.data) }
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_end = . );
PROVIDE( _data_lma = . );
} >flash AT>flash
PROVIDE( _bss_start = . );
.bss : { *(.bss) }
PROVIDE( _bss_end = . );
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
PROVIDE(_stack_begin = .);
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
PROVIDE(_stack_end = .);
_end = .;
} >ram AT>ram
}

View File

@ -1,16 +1,16 @@
#include <stdint.h>
// Timer regs
#define TIMER_BASE (0x10000000)
#define TIMER_CTRL (TIMER_BASE + (0x00))
#define TIMER_COUNT (TIMER_BASE + (0x04))
#define TIMER_VALUE (TIMER_BASE + (0x08))
// Timer0 regs
#define TIMER0_BASE (0x20000000)
#define TIMER0_CTRL (TIMER0_BASE + (0x00))
#define TIMER0_COUNT (TIMER0_BASE + (0x04))
#define TIMER0_VALUE (TIMER0_BASE + (0x08))
#define TIMER_REG(addr) (*((volatile uint32_t *)addr))
#define TIMER0_REG(addr) (*((volatile uint32_t *)addr))
static uint32_t ms_count;
static uint32_t count;
static void set_test_pass()
@ -26,15 +26,15 @@ static void set_test_fail()
int main()
{
ms_count = 0;
count = 0;
TIMER_REG(TIMER_VALUE) = 500; // 10us period
TIMER_REG(TIMER_CTRL) = 0x07; // enable interrupt and start timer
TIMER0_REG(TIMER0_VALUE) = 500; // 10us period
TIMER0_REG(TIMER0_CTRL) = 0x07; // enable interrupt and start timer
while (1) {
if (ms_count == 5) {
TIMER_REG(TIMER_CTRL) = 0x00;
ms_count = 0;
if (count == 10) {
TIMER0_REG(TIMER0_CTRL) = 0x00;
count = 0;
// TODO: do something
set_test_pass();
break;
@ -44,9 +44,9 @@ int main()
return 0;
}
void TIMER_IRQHandler()
void TIMER0_IRQHandler()
{
TIMER_REG(TIMER_CTRL) = 0x07; // clear int pending
TIMER0_REG(TIMER0_CTRL) = 0x07; // clear int pending
ms_count++;
count++;
}

View File

@ -1,23 +1,49 @@
#define REGBYTES 4
#define STORE sw
#define LOAD lw
#define REGBYTES 4
#define STORE sw
#define LOAD lw
.section .text;
.align 2;
.section .init;
.globl _start;
.type _start,@function
.weak TIMER_IRQHandler
.weak TIMER0_IRQHandler
_start:
j _reset_handler
j _timer_handler
j _timer0_handler
_reset_handler:
la sp, _sp
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _sp
li x26, 0x00
li x27, 0x00
/* Load data section */
la a0, _data_lma
la a1, _data
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, __bss_start
la a1, _end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
call main
li x26, 0x01
@ -25,6 +51,75 @@ _reset_handler:
loop:
j loop
_timer_handler:
call TIMER_IRQHandler
_timer0_handler:
addi sp, sp, -32*REGBYTES
STORE x1, 1*REGBYTES(sp)
STORE x2, 2*REGBYTES(sp)
STORE x3, 3*REGBYTES(sp)
STORE x4, 4*REGBYTES(sp)
STORE x5, 5*REGBYTES(sp)
STORE x6, 6*REGBYTES(sp)
STORE x7, 7*REGBYTES(sp)
STORE x8, 8*REGBYTES(sp)
STORE x9, 9*REGBYTES(sp)
STORE x10, 10*REGBYTES(sp)
STORE x11, 11*REGBYTES(sp)
STORE x12, 12*REGBYTES(sp)
STORE x13, 13*REGBYTES(sp)
STORE x14, 14*REGBYTES(sp)
STORE x15, 15*REGBYTES(sp)
STORE x16, 16*REGBYTES(sp)
STORE x17, 17*REGBYTES(sp)
STORE x18, 18*REGBYTES(sp)
STORE x19, 19*REGBYTES(sp)
STORE x20, 20*REGBYTES(sp)
STORE x21, 21*REGBYTES(sp)
STORE x22, 22*REGBYTES(sp)
STORE x23, 23*REGBYTES(sp)
STORE x24, 24*REGBYTES(sp)
STORE x25, 25*REGBYTES(sp)
#STORE x26, 26*REGBYTES(sp)
#STORE x27, 27*REGBYTES(sp)
STORE x28, 28*REGBYTES(sp)
STORE x29, 29*REGBYTES(sp)
STORE x30, 30*REGBYTES(sp)
STORE x31, 31*REGBYTES(sp)
call TIMER0_IRQHandler
LOAD x1, 1*REGBYTES(sp)
LOAD x2, 2*REGBYTES(sp)
LOAD x3, 3*REGBYTES(sp)
LOAD x4, 4*REGBYTES(sp)
LOAD x5, 5*REGBYTES(sp)
LOAD x6, 6*REGBYTES(sp)
LOAD x7, 7*REGBYTES(sp)
LOAD x8, 8*REGBYTES(sp)
LOAD x9, 9*REGBYTES(sp)
LOAD x10, 10*REGBYTES(sp)
LOAD x11, 11*REGBYTES(sp)
LOAD x12, 12*REGBYTES(sp)
LOAD x13, 13*REGBYTES(sp)
LOAD x14, 14*REGBYTES(sp)
LOAD x15, 15*REGBYTES(sp)
LOAD x16, 16*REGBYTES(sp)
LOAD x17, 17*REGBYTES(sp)
LOAD x18, 18*REGBYTES(sp)
LOAD x19, 19*REGBYTES(sp)
LOAD x20, 20*REGBYTES(sp)
LOAD x21, 21*REGBYTES(sp)
LOAD x22, 22*REGBYTES(sp)
LOAD x23, 23*REGBYTES(sp)
LOAD x24, 24*REGBYTES(sp)
LOAD x25, 25*REGBYTES(sp)
#LOAD x26, 26*REGBYTES(sp)
#LOAD x27, 27*REGBYTES(sp)
LOAD x28, 28*REGBYTES(sp)
LOAD x29, 29*REGBYTES(sp)
LOAD x30, 30*REGBYTES(sp)
LOAD x31, 31*REGBYTES(sp)
addi sp, sp, 32*REGBYTES
mret

Binary file not shown.

View File

@ -2,104 +2,190 @@
timer_int: file format elf32-littleriscv
Disassembly of section .text:
Disassembly of section .init:
00000000 <_start>:
0: 0080006f j 8 <_reset_handler>
4: 0200006f j 24 <_timer_handler>
4: 06c0006f j 70 <_timer0_handler>
00000008 <_reset_handler>:
8: 00001117 auipc sp,0x1
c: ff810113 addi sp,sp,-8 # 1000 <__stack_size>
10: 00000d13 li s10,0
14: 00000d93 li s11,0
18: 054000ef jal ra,6c <main>
1c: 00100d13 li s10,1
8: 10000197 auipc gp,0x10000
c: 7f818193 addi gp,gp,2040 # 10000800 <__global_pointer$>
10: 00018113 mv sp,gp
14: 00000d13 li s10,0
18: 00000d93 li s11,0
1c: 26c00513 li a0,620
20: 10000597 auipc a1,0x10000
24: fe058593 addi a1,a1,-32 # 10000000 <_data>
28: 10000617 auipc a2,0x10000
2c: fd860613 addi a2,a2,-40 # 10000000 <_data>
30: 00c5fc63 bgeu a1,a2,48 <_reset_handler+0x40>
34: 00052283 lw t0,0(a0)
38: 0055a023 sw t0,0(a1)
3c: 00450513 addi a0,a0,4
40: 00458593 addi a1,a1,4
44: fec5e8e3 bltu a1,a2,34 <_reset_handler+0x2c>
48: 10000517 auipc a0,0x10000
4c: fb850513 addi a0,a0,-72 # 10000000 <_data>
50: 80818593 addi a1,gp,-2040 # 10000008 <_end>
54: 00b57863 bgeu a0,a1,64 <_reset_handler+0x5c>
58: 00052023 sw zero,0(a0)
5c: 00450513 addi a0,a0,4
60: feb56ce3 bltu a0,a1,58 <_reset_handler+0x50>
64: 144000ef jal ra,1a8 <main>
68: 00100d13 li s10,1
00000020 <loop>:
20: 0000006f j 20 <loop>
0000006c <loop>:
6c: 0000006f j 6c <loop>
00000024 <_timer_handler>:
24: 0c8000ef jal ra,ec <TIMER_IRQHandler>
28: 30200073 mret
00000070 <_timer0_handler>:
70: f8010113 addi sp,sp,-128
74: 00112223 sw ra,4(sp)
78: 00212423 sw sp,8(sp)
7c: 00312623 sw gp,12(sp)
80: 00412823 sw tp,16(sp)
84: 00512a23 sw t0,20(sp)
88: 00612c23 sw t1,24(sp)
8c: 00712e23 sw t2,28(sp)
90: 02812023 sw s0,32(sp)
94: 02912223 sw s1,36(sp)
98: 02a12423 sw a0,40(sp)
9c: 02b12623 sw a1,44(sp)
a0: 02c12823 sw a2,48(sp)
a4: 02d12a23 sw a3,52(sp)
a8: 02e12c23 sw a4,56(sp)
ac: 02f12e23 sw a5,60(sp)
b0: 05012023 sw a6,64(sp)
b4: 05112223 sw a7,68(sp)
b8: 05212423 sw s2,72(sp)
bc: 05312623 sw s3,76(sp)
c0: 05412823 sw s4,80(sp)
c4: 05512a23 sw s5,84(sp)
c8: 05612c23 sw s6,88(sp)
cc: 05712e23 sw s7,92(sp)
d0: 07812023 sw s8,96(sp)
d4: 07912223 sw s9,100(sp)
d8: 07c12823 sw t3,112(sp)
dc: 07d12a23 sw t4,116(sp)
e0: 07e12c23 sw t5,120(sp)
e4: 07f12e23 sw t6,124(sp)
e8: 140000ef jal ra,228 <TIMER0_IRQHandler>
ec: 00412083 lw ra,4(sp)
f0: 00812103 lw sp,8(sp)
f4: 00c12183 lw gp,12(sp)
f8: 01012203 lw tp,16(sp)
fc: 01412283 lw t0,20(sp)
100: 01812303 lw t1,24(sp)
104: 01c12383 lw t2,28(sp)
108: 02012403 lw s0,32(sp)
10c: 02412483 lw s1,36(sp)
110: 02812503 lw a0,40(sp)
114: 02c12583 lw a1,44(sp)
118: 03012603 lw a2,48(sp)
11c: 03412683 lw a3,52(sp)
120: 03812703 lw a4,56(sp)
124: 03c12783 lw a5,60(sp)
128: 04012803 lw a6,64(sp)
12c: 04412883 lw a7,68(sp)
130: 04812903 lw s2,72(sp)
134: 04c12983 lw s3,76(sp)
138: 05012a03 lw s4,80(sp)
13c: 05412a83 lw s5,84(sp)
140: 05812b03 lw s6,88(sp)
144: 05c12b83 lw s7,92(sp)
148: 06012c03 lw s8,96(sp)
14c: 06412c83 lw s9,100(sp)
150: 07012e03 lw t3,112(sp)
154: 07412e83 lw t4,116(sp)
158: 07812f03 lw t5,120(sp)
15c: 07c12f83 lw t6,124(sp)
160: 08010113 addi sp,sp,128
164: 30200073 mret
0000002c <set_test_pass>:
2c: ff010113 addi sp,sp,-16
30: 00812623 sw s0,12(sp)
34: 01010413 addi s0,sp,16
38: 00100d93 li s11,1
3c: 00000013 nop
40: 00c12403 lw s0,12(sp)
44: 01010113 addi sp,sp,16
48: 00008067 ret
Disassembly of section .text:
0000004c <set_test_fail>:
4c: ff010113 addi sp,sp,-16
50: 00812623 sw s0,12(sp)
54: 01010413 addi s0,sp,16
58: 00000d93 li s11,0
5c: 00000013 nop
60: 00c12403 lw s0,12(sp)
64: 01010113 addi sp,sp,16
68: 00008067 ret
00000168 <set_test_pass>:
168: ff010113 addi sp,sp,-16
16c: 00812623 sw s0,12(sp)
170: 01010413 addi s0,sp,16
174: 00100d93 li s11,1
178: 00000013 nop
17c: 00c12403 lw s0,12(sp)
180: 01010113 addi sp,sp,16
184: 00008067 ret
0000006c <main>:
6c: ff010113 addi sp,sp,-16
70: 00112623 sw ra,12(sp)
74: 00812423 sw s0,8(sp)
78: 01010413 addi s0,sp,16
7c: 00001797 auipc a5,0x1
80: f8478793 addi a5,a5,-124 # 1000 <__stack_size>
84: 0007a023 sw zero,0(a5)
88: 100007b7 lui a5,0x10000
8c: 00878793 addi a5,a5,8 # 10000008 <__stack_size+0xffff008>
90: 1f400713 li a4,500
94: 00e7a023 sw a4,0(a5)
98: 100007b7 lui a5,0x10000
9c: 00700713 li a4,7
a0: 00e7a023 sw a4,0(a5) # 10000000 <__stack_size+0xffff000>
a4: 00001797 auipc a5,0x1
a8: f5c78793 addi a5,a5,-164 # 1000 <__stack_size>
ac: 0007a703 lw a4,0(a5)
b0: 00500793 li a5,5
b4: fef718e3 bne a4,a5,a4 <main+0x38>
b8: 100007b7 lui a5,0x10000
bc: 0007a023 sw zero,0(a5) # 10000000 <__stack_size+0xffff000>
c0: 00001797 auipc a5,0x1
c4: f4078793 addi a5,a5,-192 # 1000 <__stack_size>
c8: 0007a023 sw zero,0(a5)
cc: f61ff0ef jal ra,2c <set_test_pass>
d0: 00000013 nop
d4: 00000793 li a5,0
d8: 00078513 mv a0,a5
dc: 00c12083 lw ra,12(sp)
e0: 00812403 lw s0,8(sp)
e4: 01010113 addi sp,sp,16
e8: 00008067 ret
00000188 <set_test_fail>:
188: ff010113 addi sp,sp,-16
18c: 00812623 sw s0,12(sp)
190: 01010413 addi s0,sp,16
194: 00000d93 li s11,0
198: 00000013 nop
19c: 00c12403 lw s0,12(sp)
1a0: 01010113 addi sp,sp,16
1a4: 00008067 ret
000000ec <TIMER_IRQHandler>:
ec: ff010113 addi sp,sp,-16
f0: 00812623 sw s0,12(sp)
f4: 01010413 addi s0,sp,16
f8: 100007b7 lui a5,0x10000
fc: 00700713 li a4,7
100: 00e7a023 sw a4,0(a5) # 10000000 <__stack_size+0xffff000>
104: 00001797 auipc a5,0x1
108: efc78793 addi a5,a5,-260 # 1000 <__stack_size>
10c: 0007a783 lw a5,0(a5)
110: 00178713 addi a4,a5,1
114: 00001797 auipc a5,0x1
118: eec78793 addi a5,a5,-276 # 1000 <__stack_size>
11c: 00e7a023 sw a4,0(a5)
120: 00000013 nop
124: 00c12403 lw s0,12(sp)
128: 01010113 addi sp,sp,16
12c: 00008067 ret
000001a8 <main>:
1a8: ff010113 addi sp,sp,-16
1ac: 00112623 sw ra,12(sp)
1b0: 00812423 sw s0,8(sp)
1b4: 01010413 addi s0,sp,16
1b8: 10000797 auipc a5,0x10000
1bc: e4878793 addi a5,a5,-440 # 10000000 <_data>
1c0: 0007a023 sw zero,0(a5)
1c4: 200007b7 lui a5,0x20000
1c8: 00878793 addi a5,a5,8 # 20000008 <__global_pointer$+0xffff808>
1cc: 1f400713 li a4,500
1d0: 00e7a023 sw a4,0(a5)
1d4: 200007b7 lui a5,0x20000
1d8: 00700713 li a4,7
1dc: 00e7a023 sw a4,0(a5) # 20000000 <__global_pointer$+0xffff800>
1e0: 10000797 auipc a5,0x10000
1e4: e2078793 addi a5,a5,-480 # 10000000 <_data>
1e8: 0007a703 lw a4,0(a5)
1ec: 00a00793 li a5,10
1f0: fef718e3 bne a4,a5,1e0 <main+0x38>
1f4: 200007b7 lui a5,0x20000
1f8: 0007a023 sw zero,0(a5) # 20000000 <__global_pointer$+0xffff800>
1fc: 10000797 auipc a5,0x10000
200: e0478793 addi a5,a5,-508 # 10000000 <_data>
204: 0007a023 sw zero,0(a5)
208: f61ff0ef jal ra,168 <set_test_pass>
20c: 00000013 nop
210: 00000793 li a5,0
214: 00078513 mv a0,a5
218: 00c12083 lw ra,12(sp)
21c: 00812403 lw s0,8(sp)
220: 01010113 addi sp,sp,16
224: 00008067 ret
00000228 <TIMER0_IRQHandler>:
228: ff010113 addi sp,sp,-16
22c: 00812623 sw s0,12(sp)
230: 01010413 addi s0,sp,16
234: 200007b7 lui a5,0x20000
238: 00700713 li a4,7
23c: 00e7a023 sw a4,0(a5) # 20000000 <__global_pointer$+0xffff800>
240: 10000797 auipc a5,0x10000
244: dc078793 addi a5,a5,-576 # 10000000 <_data>
248: 0007a783 lw a5,0(a5)
24c: 00178713 addi a4,a5,1
250: 10000797 auipc a5,0x10000
254: db078793 addi a5,a5,-592 # 10000000 <_data>
258: 00e7a023 sw a4,0(a5)
25c: 00000013 nop
260: 00c12403 lw s0,12(sp)
264: 01010113 addi sp,sp,16
268: 00008067 ret
Disassembly of section .bss:
00001000 <_end>:
1000: 0000 unimp
10000000 <__bss_start>:
10000000: 0000 unimp
...
Disassembly of section .stack:
10000400 <_sp-0x400>:
...
Disassembly of section .comment:
@ -109,11 +195,11 @@ Disassembly of section .comment:
4: 2820 fld fs0,80(s0)
6: 20554e47 fmsub.s ft8,fa0,ft5,ft4,rmm
a: 434d li t1,19
c: 2055 jal b0 <main+0x44>
c: 2055 jal b0 <_timer0_handler+0x40>
e: 6345 lui t1,0x11
10: 696c flw fa1,84(a0)
12: 7370 flw fa2,100(a4)
14: 2065 jal bc <main+0x50>
14: 2065 jal bc <_timer0_handler+0x4c>
16: 4952 lw s2,20(sp)
18: 562d4353 0x562d4353
1c: 4520 lw s0,72(a0)