/* 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