373 lines
12 KiB
Verilog
373 lines
12 KiB
Verilog
/*
|
|
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"
|
|
|
|
// tinyriscv处理器核顶层模块
|
|
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, // jtag模块读、写寄存器的地址
|
|
input wire[`RegBus] jtag_reg_data_i, // jtag模块写寄存器数据
|
|
input wire jtag_reg_we_i, // jtag模块写寄存器标志
|
|
output wire[`RegBus] jtag_reg_data_o, // jtag模块读取到的寄存器数据
|
|
|
|
input wire rib_hold_flag_i, // 总线暂停标志
|
|
input wire jtag_halt_flag_i, // jtag暂停标志
|
|
input wire jtag_reset_flag_i, // jtag复位PC标志
|
|
|
|
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;
|
|
wire[`INT_BUS] if_int_flag_o;
|
|
|
|
// id模块输出信号
|
|
wire[`RegAddrBus] id_reg1_raddr_o;
|
|
wire[`RegAddrBus] id_reg2_raddr_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;
|
|
wire[`MemAddrBus] id_csr_raddr_o;
|
|
wire id_csr_we_o;
|
|
wire[`RegBus] id_csr_rdata_o;
|
|
wire[`MemAddrBus] id_csr_waddr_o;
|
|
wire[`MemAddrBus] id_op1_o;
|
|
wire[`MemAddrBus] id_op2_o;
|
|
wire[`MemAddrBus] id_op1_jump_o;
|
|
wire[`MemAddrBus] id_op2_jump_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;
|
|
wire ie_csr_we_o;
|
|
wire[`MemAddrBus] ie_csr_waddr_o;
|
|
wire[`RegBus] ie_csr_rdata_o;
|
|
wire[`MemAddrBus] ie_op1_o;
|
|
wire[`MemAddrBus] ie_op2_o;
|
|
wire[`MemAddrBus] ie_op1_jump_o;
|
|
wire[`MemAddrBus] ie_op2_jump_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[`RegBus] ex_csr_wdata_o;
|
|
wire ex_csr_we_o;
|
|
wire[`MemAddrBus] ex_csr_waddr_o;
|
|
|
|
// regs模块输出信号
|
|
wire[`RegBus] regs_rdata1_o;
|
|
wire[`RegBus] regs_rdata2_o;
|
|
|
|
// csr_reg模块输出信号
|
|
wire[`RegBus] csr_data_o;
|
|
wire[`RegBus] csr_clint_data_o;
|
|
wire csr_global_int_en_o;
|
|
wire[`RegBus] csr_clint_csr_mtvec;
|
|
wire[`RegBus] csr_clint_csr_mepc;
|
|
wire[`RegBus] csr_clint_csr_mstatus;
|
|
|
|
// 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 clint_we_o;
|
|
wire[`MemAddrBus] clint_waddr_o;
|
|
wire[`MemAddrBus] clint_raddr_o;
|
|
wire[`RegBus] clint_data_o;
|
|
wire[`InstAddrBus] clint_int_addr_o;
|
|
wire clint_int_assert_o;
|
|
wire clint_hold_flag_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;
|
|
assign rib_ex_we_o = ex_mem_we_o;
|
|
|
|
assign rib_pc_addr_o = pc_pc_o;
|
|
|
|
|
|
// pc_reg模块例化
|
|
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模块例化
|
|
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),
|
|
.hold_flag_clint_i(clint_hold_flag_o),
|
|
.jump_flag_o(ctrl_jump_flag_o),
|
|
.jump_addr_o(ctrl_jump_addr_o),
|
|
.jtag_halt_flag_i(jtag_halt_flag_i)
|
|
);
|
|
|
|
// regs模块例化
|
|
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)
|
|
);
|
|
|
|
// csr_reg模块例化
|
|
csr_reg u_csr_reg(
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.we_i(ex_csr_we_o),
|
|
.raddr_i(id_csr_raddr_o),
|
|
.waddr_i(ex_csr_waddr_o),
|
|
.data_i(ex_csr_wdata_o),
|
|
.data_o(csr_data_o),
|
|
.global_int_en_o(csr_global_int_en_o),
|
|
.clint_we_i(clint_we_o),
|
|
.clint_raddr_i(clint_raddr_o),
|
|
.clint_waddr_i(clint_waddr_o),
|
|
.clint_data_i(clint_data_o),
|
|
.clint_data_o(csr_clint_data_o),
|
|
.clint_csr_mtvec(csr_clint_csr_mtvec),
|
|
.clint_csr_mepc(csr_clint_csr_mepc),
|
|
.clint_csr_mstatus(csr_clint_csr_mstatus)
|
|
);
|
|
|
|
// if_id模块例化
|
|
if_id u_if_id(
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.inst_i(rib_pc_data_i),
|
|
.inst_addr_i(pc_pc_o),
|
|
.int_flag_i(int_i),
|
|
.int_flag_o(if_int_flag_o),
|
|
.hold_flag_i(ctrl_hold_flag_o),
|
|
.inst_o(if_inst_o),
|
|
.inst_addr_o(if_inst_addr_o)
|
|
);
|
|
|
|
// id模块例化
|
|
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),
|
|
.reg1_raddr_o(id_reg1_raddr_o),
|
|
.reg2_raddr_o(id_reg2_raddr_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),
|
|
.op1_o(id_op1_o),
|
|
.op2_o(id_op2_o),
|
|
.op1_jump_o(id_op1_jump_o),
|
|
.op2_jump_o(id_op2_jump_o),
|
|
.csr_rdata_i(csr_data_o),
|
|
.csr_raddr_o(id_csr_raddr_o),
|
|
.csr_we_o(id_csr_we_o),
|
|
.csr_rdata_o(id_csr_rdata_o),
|
|
.csr_waddr_o(id_csr_waddr_o)
|
|
);
|
|
|
|
// id_ex模块例化
|
|
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),
|
|
.op1_i(id_op1_o),
|
|
.op2_i(id_op2_o),
|
|
.op1_jump_i(id_op1_jump_o),
|
|
.op2_jump_i(id_op2_jump_o),
|
|
.op1_o(ie_op1_o),
|
|
.op2_o(ie_op2_o),
|
|
.op1_jump_o(ie_op1_jump_o),
|
|
.op2_jump_o(ie_op2_jump_o),
|
|
.csr_we_i(id_csr_we_o),
|
|
.csr_waddr_i(id_csr_waddr_o),
|
|
.csr_rdata_i(id_csr_rdata_o),
|
|
.csr_we_o(ie_csr_we_o),
|
|
.csr_waddr_o(ie_csr_waddr_o),
|
|
.csr_rdata_o(ie_csr_rdata_o)
|
|
);
|
|
|
|
// ex模块例化
|
|
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),
|
|
.op1_i(ie_op1_o),
|
|
.op2_i(ie_op2_o),
|
|
.op1_jump_i(ie_op1_jump_o),
|
|
.op2_jump_i(ie_op2_jump_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),
|
|
.hold_flag_o(ex_hold_flag_o),
|
|
.jump_flag_o(ex_jump_flag_o),
|
|
.jump_addr_o(ex_jump_addr_o),
|
|
.int_assert_i(clint_int_assert_o),
|
|
.int_addr_i(clint_int_addr_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),
|
|
.csr_we_i(ie_csr_we_o),
|
|
.csr_waddr_i(ie_csr_waddr_o),
|
|
.csr_rdata_i(ie_csr_rdata_o),
|
|
.csr_wdata_o(ex_csr_wdata_o),
|
|
.csr_we_o(ex_csr_we_o),
|
|
.csr_waddr_o(ex_csr_waddr_o)
|
|
);
|
|
|
|
// div模块例化
|
|
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模块例化
|
|
clint u_clint(
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.int_flag_i(if_int_flag_o),
|
|
.inst_i(id_inst_o),
|
|
.inst_addr_i(id_inst_addr_o),
|
|
.jump_flag_i(ex_jump_flag_o),
|
|
.jump_addr_i(ex_jump_addr_o),
|
|
.hold_flag_i(ctrl_hold_flag_o),
|
|
.div_started_i(ex_div_start_o),
|
|
.data_i(csr_clint_data_o),
|
|
.csr_mtvec(csr_clint_csr_mtvec),
|
|
.csr_mepc(csr_clint_csr_mepc),
|
|
.csr_mstatus(csr_clint_csr_mstatus),
|
|
.we_o(clint_we_o),
|
|
.waddr_o(clint_waddr_o),
|
|
.raddr_o(clint_raddr_o),
|
|
.data_o(clint_data_o),
|
|
.hold_flag_o(clint_hold_flag_o),
|
|
.global_int_en_i(csr_global_int_en_o),
|
|
.int_addr_o(clint_int_addr_o),
|
|
.int_assert_o(clint_int_assert_o)
|
|
);
|
|
|
|
endmodule
|