rtl: add reset ctrl module

Signed-off-by: liangkangnan <liangkangnan@163.com>
bram
liangkangnan 2020-11-18 22:15:08 +08:00
parent ceddc1af24
commit f03f42fc9b
11 changed files with 195 additions and 75 deletions

View File

@ -7,16 +7,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property PACKAGE_PIN N14 [get_ports clk]
# 复位引脚
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN L13 [get_ports rst_n]
# 程序执行完毕指示引脚
set_property IOSTANDARD LVCMOS33 [get_ports over]
set_property PACKAGE_PIN M16 [get_ports over]
# 程序执行成功指示引脚
set_property IOSTANDARD LVCMOS33 [get_ports succ]
set_property PACKAGE_PIN N16 [get_ports succ]
set_property IOSTANDARD LVCMOS33 [get_ports rst_ext_i]
set_property PACKAGE_PIN L13 [get_ports rst_ext_i]
# CPU停住指示引脚
set_property IOSTANDARD LVCMOS33 [get_ports halted_ind]

View File

@ -128,15 +128,23 @@ module exu_alu_datapath(
wire[31:0] slt_res = (~op1_ge_op2_signed)? 32'h1: 32'h0;
wire[31:0] sltu_res = (~op1_ge_op2_unsigned)? 32'h1: 32'h0;
wire[31:0] alu_datapath_res = ({32{op_xor}} & xor_res) |
({32{op_or}} & or_res) |
({32{op_and}} & and_res) |
({32{op_add | op_sub}} & add_sub_res) |
({32{op_sll}} & sll_res) |
({32{op_srl}} & srl_res) |
({32{op_sra}} & sra_res) |
({32{op_slt}} & slt_res) |
({32{op_sltu}} & sltu_res);
reg[31:0] alu_datapath_res;
always @ (*) begin
alu_datapath_res = 32'h0;
case (1'b1)
op_xor: alu_datapath_res = xor_res;
op_or: alu_datapath_res = or_res;
op_and: alu_datapath_res = and_res;
op_add: alu_datapath_res = add_sub_res;
op_sub: alu_datapath_res = add_sub_res;
op_sll: alu_datapath_res = sll_res;
op_srl: alu_datapath_res = srl_res;
op_sra: alu_datapath_res = sra_res;
op_slt: alu_datapath_res = slt_res;
op_sltu: alu_datapath_res = sltu_res;
endcase
end
assign alu_res_o = alu_datapath_res;

View File

@ -59,16 +59,34 @@ module exu_commit(
assign reg_we_o = muldiv_reg_we_i | mem_reg_we_i | csr_reg_we_i | use_alu_res | bjp_reg_we_i;
assign reg_waddr_o = ({5{muldiv_reg_we_i}} & muldiv_reg_waddr_i) |
({5{mem_reg_we_i}} & mem_reg_waddr_i) |
({5{csr_reg_we_i}} & csr_reg_waddr_i) |
({5{bjp_reg_we_i}} & bjp_reg_waddr_i) |
({5{rd_we_i}} & rd_waddr_i);
reg[4:0] reg_waddr;
assign reg_wdata_o = ({32{muldiv_reg_we_i}} & muldiv_reg_wdata_i) |
({32{mem_reg_we_i}} & mem_reg_wdata_i) |
({32{csr_reg_we_i}} & csr_reg_wdata_i) |
({32{bjp_reg_we_i}} & bjp_reg_wdata_i) |
({32{use_alu_res}} & alu_reg_wdata_i);
always @ (*) begin
reg_waddr = 5'h0;
case (1'b1)
muldiv_reg_we_i: reg_waddr = muldiv_reg_waddr_i;
mem_reg_we_i: reg_waddr = mem_reg_waddr_i;
csr_reg_we_i: reg_waddr = csr_reg_waddr_i;
bjp_reg_we_i: reg_waddr = bjp_reg_waddr_i;
rd_we_i: reg_waddr = rd_waddr_i;
endcase
end
assign reg_waddr_o = reg_waddr;
reg[31:0] reg_wdata;
always @ (*) begin
reg_wdata = 32'h0;
case (1'b1)
muldiv_reg_we_i: reg_wdata = muldiv_reg_wdata_i;
mem_reg_we_i: reg_wdata = mem_reg_wdata_i;
csr_reg_we_i: reg_wdata = csr_reg_wdata_i;
bjp_reg_we_i: reg_wdata = bjp_reg_wdata_i;
use_alu_res: reg_wdata = alu_reg_wdata_i;
endcase
end
assign reg_wdata_o = reg_wdata;
endmodule

View File

@ -61,36 +61,71 @@ module exu_mem(
assign mem_sel_o[2] = mem_addr_index10 | mem_op_sw_i;
assign mem_sel_o[3] = mem_addr_index11 | (mem_op_sh_i & mem_addr_index10) | mem_op_sw_i;
// store
wire[31:0] sb_res = ({32{mem_addr_index00}} & {24'h0, mem_rs2_data_i[7:0]}) |
({32{mem_addr_index01}} & {16'h0, mem_rs2_data_i[7:0], 8'h0}) |
({32{mem_addr_index10}} & {8'h0, mem_rs2_data_i[7:0], 16'h0}) |
({32{mem_addr_index11}} & {mem_rs2_data_i[7:0], 24'h0});
reg[31:0] sb_res;
wire[31:0] sh_res = ({32{mem_addr_index00}} & {16'h0, mem_rs2_data_i[15:0]}) |
({32{mem_addr_index10}} & {mem_rs2_data_i[15:0], 16'h0});
always @ (*) begin
sb_res = 32'h0;
case (1'b1)
mem_addr_index00: sb_res = {24'h0, mem_rs2_data_i[7:0]};
mem_addr_index01: sb_res = {16'h0, mem_rs2_data_i[7:0], 8'h0};
mem_addr_index10: sb_res = {8'h0, mem_rs2_data_i[7:0], 16'h0};
mem_addr_index11: sb_res = {mem_rs2_data_i[7:0], 24'h0};
endcase
end
reg[31:0] sh_res;
always @ (*) begin
sh_res = 32'h0;
case (1'b1)
mem_addr_index00: sh_res = {16'h0, mem_rs2_data_i[15:0]};
mem_addr_index10: sh_res = {mem_rs2_data_i[15:0], 16'h0};
endcase
end
wire[31:0] sw_res = mem_rs2_data_i;
// load
wire[31:0] lb_res = ({32{mem_addr_index00}} & {{24{mem_op_lb_i & mem_rdata_i[7]}}, mem_rdata_i[7:0]}) |
({32{mem_addr_index01}} & {{24{mem_op_lb_i & mem_rdata_i[15]}}, mem_rdata_i[15:8]}) |
({32{mem_addr_index10}} & {{24{mem_op_lb_i & mem_rdata_i[23]}}, mem_rdata_i[23:16]}) |
({32{mem_addr_index11}} & {{24{mem_op_lb_i & mem_rdata_i[31]}}, mem_rdata_i[31:24]});
reg[31:0] lb_res;
wire[31:0] lh_res = ({32{mem_addr_index00}} & {{24{mem_op_lh_i & mem_rdata_i[15]}}, mem_rdata_i[15:0]}) |
({32{mem_addr_index10}} & {{24{mem_op_lh_i & mem_rdata_i[31]}}, mem_rdata_i[31:16]});
always @ (*) begin
lb_res = 32'h0;
case (1'b1)
mem_addr_index00: lb_res = {{24{mem_op_lb_i & mem_rdata_i[7]}}, mem_rdata_i[7:0]};
mem_addr_index01: lb_res = {{24{mem_op_lb_i & mem_rdata_i[15]}}, mem_rdata_i[15:8]};
mem_addr_index10: lb_res = {{24{mem_op_lb_i & mem_rdata_i[23]}}, mem_rdata_i[23:16]};
mem_addr_index11: lb_res = {{24{mem_op_lb_i & mem_rdata_i[31]}}, mem_rdata_i[31:24]};
endcase
end
reg[31:0] lh_res;
always @ (*) begin
lh_res = 32'h0;
case (1'b1)
mem_addr_index00: lh_res = {{24{mem_op_lh_i & mem_rdata_i[15]}}, mem_rdata_i[15:0]};
mem_addr_index10: lh_res = {{24{mem_op_lh_i & mem_rdata_i[31]}}, mem_rdata_i[31:16]};
endcase
end
wire[31:0] lw_res = mem_rdata_i;
//
assign mem_wdata_o = ({32{mem_op_sb_i}} & sb_res) |
({32{mem_op_sh_i}} & sh_res) |
({32{mem_op_sw_i}} & sw_res) |
({32{mem_op_lb_i | mem_op_lbu_i}} & lb_res) |
({32{mem_op_lh_i | mem_op_lhu_i}} & lh_res) |
({32{mem_op_lw_i}} & lw_res);
reg[31:0] mem_wdata;
always @ (*) begin
mem_wdata = 32'h0;
case (1'b1)
mem_op_sb_i: mem_wdata = sb_res;
mem_op_sh_i: mem_wdata = sh_res;
mem_op_sw_i: mem_wdata = sw_res;
mem_op_lb_i: mem_wdata = lb_res;
mem_op_lbu_i: mem_wdata = lb_res;
mem_op_lh_i: mem_wdata = lh_res;
mem_op_lhu_i: mem_wdata = lh_res;
mem_op_lw_i: mem_wdata = lw_res;
endcase
end
assign mem_wdata_o = mem_wdata;
wire mem_req_hsked = (mem_req_valid_o & mem_req_ready_i);
wire mem_rsp_hsked = (mem_rsp_valid_i & mem_rsp_ready_o);

View File

@ -86,10 +86,17 @@ module exu_muldiv(
wire[31:0] mulh_res = (op1_is_signed ^ op2_is_signed)? mul_res_tmp_complcode[63:32]: mul_res_tmp[63:32];
wire[31:0] mulhsu_res = (op1_is_signed)? mul_res_tmp_complcode[63:32]: mul_res_tmp[63:32];
wire[31:0] mul_op_res = ({32{muldiv_op_mul_i}} & mul_res) |
({32{muldiv_op_mulhu_i}} & mulhu_res) |
({32{muldiv_op_mulh_i}} & mulh_res) |
({32{muldiv_op_mulhsu_i}} & mulhsu_res);
reg[31:0] mul_op_res;
always @ (*) begin
mul_op_res = 32'h0;
case (1'b1)
muldiv_op_mul_i: mul_op_res = mul_res;
muldiv_op_mulhu_i: mul_op_res = mulhu_res;
muldiv_op_mulh_i: mul_op_res = mulh_res;
muldiv_op_mulhsu_i: mul_op_res = mulhsu_res;
endcase
end
//
assign muldiv_reg_wdata_o = div_result | mul_op_res;

View File

@ -46,6 +46,7 @@ module ifu(
assign req_valid_o = (~rst_n)? 1'b0:
(flush_i)? 1'b0:
stall_i[`STALL_PC]? 1'b0:
jtag_halt_i? 1'b0:
1'b1;
assign rsp_ready_o = (~rst_n)? 1'b0: 1'b1;
@ -53,7 +54,7 @@ module ifu(
wire ifu_rsp_hsked = (rsp_valid_i & rsp_ready_o);
// 线
wire stall = stall_i[`STALL_PC] | (~ifu_req_hsked) | jtag_halt_i;
wire stall = stall_i[`STALL_PC] | (~ifu_req_hsked);
reg[31:0] pc;
reg[31:0] pc_prev;

55
rtl/core/rst_ctrl.v Normal file
View File

@ -0,0 +1,55 @@
/*
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.
*/
//
module rst_ctrl(
input wire clk,
input wire rst_ext_i,
input wire rst_jtag_i,
output wire core_rst_n_o,
output wire jtag_rst_n_o
);
wire ext_rst_r;
gen_ticks_sync #(
.DP(2),
.DW(1)
) ext_rst_sync(
.rst_n(rst_ext_i),
.clk(clk),
.din(1'b1),
.dout(ext_rst_r)
);
reg jtag_rst_r;
always @ (posedge clk or posedge rst_jtag_i) begin
if (rst_jtag_i) begin
jtag_rst_r <= 1'b0;
end else begin
jtag_rst_r <= 1'b1;
end
end
assign core_rst_n_o = ext_rst_r & jtag_rst_r;
assign jtag_rst_n_o = ext_rst_r;
endmodule

View File

@ -20,10 +20,8 @@
module tinyriscv_soc_top(
input wire clk,
input wire rst_n,
input wire rst_ext_i,
output reg over, //
output reg succ, //
output wire halted_ind, // jtaghaltCPU
output wire uart_tx_pin, // UART
@ -147,6 +145,8 @@ module tinyriscv_soc_top(
// tinyriscv
wire[`INT_WIDTH-1:0] int_flag;
wire rst_n;
wire jtag_rst_n;
// timer0
wire timer0_int;
@ -158,20 +158,19 @@ module tinyriscv_soc_top(
assign int_flag = {{(`INT_WIDTH-1){1'b0}}, timer0_int};
//
rst_ctrl u_rst_ctrl(
.clk(clk),
.rst_ext_i(rst_ext_i),
.rst_jtag_i(jtag_reset_req_o),
.core_rst_n_o(rst_n),
.jtag_rst_n_o(jtag_rst_n)
);
// LED
// haltCPU
assign halted_ind = ~jtag_halt_req_o;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
over <= 1'b1;
succ <= 1'b1;
end else begin
over <= ~u_tinyriscv_core.u_gpr_reg.regs[26]; // when = 1, run over
succ <= ~u_tinyriscv_core.u_gpr_reg.regs[27]; // when = 1, run succ, otherwise fail
end
end
// tinyriscv
tinyriscv_core u_tinyriscv_core(
.clk(clk),
@ -302,7 +301,7 @@ module tinyriscv_soc_top(
.DMI_OP_BITS(2)
) u_jtag_top(
.clk(clk),
.jtag_rst_n(rst_n),
.jtag_rst_n(jtag_rst_n),
.jtag_pin_TCK(jtag_TCK),
.jtag_pin_TMS(jtag_TMS),
.jtag_pin_TDI(jtag_TDI),

View File

@ -44,6 +44,7 @@ def main():
iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu_idu.v')
iverilog_cmd.append(rtl_dir + r'/rtl/core/pipe_ctrl.v')
iverilog_cmd.append(rtl_dir + r'/rtl/core/tinyriscv_core.v')
iverilog_cmd.append(rtl_dir + r'/rtl/core/rst_ctrl.v')
# ../rtl/perips
iverilog_cmd.append(rtl_dir + r'/rtl/perips/ram.v')
iverilog_cmd.append(rtl_dir + r'/rtl/perips/rom.v')

View File

@ -44,14 +44,16 @@ module tinyriscv_soc_tb;
initial begin
clk = 0;
rst_n = 1'b0;
rst_n = 1'b1;
`ifdef TEST_JTAG
TCK = 1;
TMS = 1;
TDI = 1;
`endif
$display("test running...");
#40
#100
rst_n = 1'b0;
#100
rst_n = 1'b1;
#200
/*
@ -520,7 +522,7 @@ module tinyriscv_soc_tb;
tinyriscv_soc_top tinyriscv_soc_top_0(
.clk(clk),
.rst_n(rst_n)
.rst_ext_i(rst_n)
`ifdef TEST_JTAG
,
.jtag_TCK(TCK),

View File

@ -39,14 +39,16 @@ module tinyriscv_soc_tb;
initial begin
clk = 0;
rst_n = 1'b0;
rst_n = 1'b1;
`ifdef TEST_JTAG
TCK = 1;
TMS = 1;
TDI = 1;
`endif
$display("test running...");
#40
#100
rst_n = 1'b0;
#100
rst_n = 1'b1;
#200
@ -506,7 +508,7 @@ module tinyriscv_soc_tb;
tinyriscv_soc_top tinyriscv_soc_top_0(
.clk(clk),
.rst_n(rst_n)
.rst_ext_i(rst_n)
`ifdef TEST_JTAG
,
.jtag_TCK(TCK),