temp commit

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-04-29 19:27:25 +08:00
parent 77812d60df
commit f9412fca3c
15 changed files with 823 additions and 626 deletions

View File

@ -38,7 +38,8 @@ module csr_reg(
output wire[31:0] mepc_o, // mepc寄存器值 output wire[31:0] mepc_o, // mepc寄存器值
output wire[31:0] mstatus_o, // mstatus寄存器值 output wire[31:0] mstatus_o, // mstatus寄存器值
output wire[31:0] mie_o, // mie寄存器值 output wire[31:0] mie_o, // mie寄存器值
output wire[31:0] dpc_o // dpc寄存器值 output wire[31:0] dpc_o, // dpc寄存器值
output wire[31:0] dcsr_o // dcsr寄存器值
); );
@ -72,6 +73,9 @@ module csr_reg(
reg[31:0] dpc_d; reg[31:0] dpc_d;
wire[31:0] dpc_q; wire[31:0] dpc_q;
reg dpc_we; reg dpc_we;
reg[31:0] dcsr_d;
wire[31:0] dcsr_q;
reg dcsr_we;
reg[63:0] cycle; reg[63:0] cycle;
@ -90,6 +94,7 @@ module csr_reg(
assign mstatus_o = mstatus_q; assign mstatus_o = mstatus_q;
assign mie_o = mie_q; assign mie_o = mie_q;
assign dpc_o = dpc_q; assign dpc_o = dpc_q;
assign dcsr_o = dcsr_q;
reg[31:0] exu_rdata; reg[31:0] exu_rdata;
@ -132,6 +137,9 @@ module csr_reg(
`CSR_DPC: begin `CSR_DPC: begin
exu_rdata = dpc_q; exu_rdata = dpc_q;
end end
`CSR_DCSR: begin
exu_rdata = dcsr_q;
end
default: begin default: begin
exu_rdata = 32'h0; exu_rdata = 32'h0;
end end
@ -166,6 +174,8 @@ module csr_reg(
mhartid_we = 1'b0; mhartid_we = 1'b0;
dpc_d = dpc_q; dpc_d = dpc_q;
dpc_we = 1'b0; dpc_we = 1'b0;
dcsr_d = dcsr_q;
dcsr_we = 1'b0;
if (we) begin if (we) begin
case (waddr[11:0]) case (waddr[11:0])
@ -209,6 +219,10 @@ module csr_reg(
dpc_d = wdata; dpc_d = wdata;
dpc_we = 1'b1; dpc_we = 1'b1;
end end
`CSR_DCSR: begin
dcsr_d = wdata;
dcsr_we = 1'b1;
end
default:; default:;
endcase endcase
end end
@ -324,4 +338,15 @@ module csr_reg(
.rdata_o(dpc_q) .rdata_o(dpc_q)
); );
// dcsr
csr #(
.RESET_VAL(32'h0)
) dcsr_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(dcsr_d),
.we_i(dcsr_we),
.rdata_o(dcsr_q)
);
endmodule endmodule

View File

@ -46,6 +46,7 @@ module exception (
input wire[31:0] mstatus_i, // mstatus寄存器 input wire[31:0] mstatus_i, // mstatus寄存器
input wire[31:0] mie_i, // mie寄存器 input wire[31:0] mie_i, // mie寄存器
input wire[31:0] dpc_i, // dpc寄存器 input wire[31:0] dpc_i, // dpc寄存器
input wire[31:0] dcsr_i, // dcsr寄存器
input wire irq_software_i, input wire irq_software_i,
input wire irq_timer_i, input wire irq_timer_i,
@ -159,7 +160,7 @@ module exception (
exception_req = 1'b1; exception_req = 1'b1;
exception_cause = `CAUSE_EXCEP_ECALL_M; exception_cause = `CAUSE_EXCEP_ECALL_M;
exception_offset = ECALL_OFFSET; exception_offset = ECALL_OFFSET;
end else if (inst_ebreak_i) begin end else if (inst_ebreak_i & (!dcsr_i[15])) begin
exception_req = 1'b1; exception_req = 1'b1;
exception_cause = `CAUSE_EXCEP_EBREAK_M; exception_cause = `CAUSE_EXCEP_EBREAK_M;
exception_offset = EBREAK_OFFSET; exception_offset = EBREAK_OFFSET;
@ -178,7 +179,7 @@ module exception (
assign int_or_exception_cause = exception_req ? exception_cause : interrupt_cause; assign int_or_exception_cause = exception_req ? exception_cause : interrupt_cause;
assign int_or_exception_offset = exception_req ? exception_offset : interrupt_offset; assign int_or_exception_offset = exception_req ? exception_offset : interrupt_offset;
wire debug_mode_req = (~debug_mode_q) & debug_req_i & inst_valid_i; wire debug_mode_req = ((~debug_mode_q) & debug_req_i & inst_valid_i) | (inst_ebreak_i & dcsr_i[15]);
assign stall_flag_o = ((state_q != S_IDLE) & (state_q != S_ASSERT)) | assign stall_flag_o = ((state_q != S_IDLE) & (state_q != S_ASSERT)) |
(interrupt_req & global_int_en) | exception_req | (interrupt_req & global_int_en) | exception_req |
@ -206,9 +207,11 @@ module exception (
state_d = S_W_MEPC; state_d = S_W_MEPC;
end else if (debug_mode_req) begin end else if (debug_mode_req) begin
debug_mode_d = 1'b1; debug_mode_d = 1'b1;
if (!inst_ebreak_i) begin
csr_we = 1'b1; csr_we = 1'b1;
csr_waddr = {20'h0, `CSR_DPC}; csr_waddr = {20'h0, `CSR_DPC};
csr_wdata = inst_addr_i; csr_wdata = inst_addr_i;
end
assert_addr_d = debug_halt_addr_i; assert_addr_d = debug_halt_addr_i;
state_d = S_ASSERT; state_d = S_ASSERT;
end else if (inst_mret_i) begin end else if (inst_mret_i) begin

View File

@ -128,6 +128,7 @@ module tinyriscv_core #(
wire[31:0] csr_mstatus_o; wire[31:0] csr_mstatus_o;
wire[31:0] csr_mie_o; wire[31:0] csr_mie_o;
wire[31:0] csr_dpc_o; wire[31:0] csr_dpc_o;
wire[31:0] csr_dcsr_o;
// pipe_ctrl模块输出信号 // pipe_ctrl模块输出信号
wire[31:0] ctrl_flush_addr_o; wire[31:0] ctrl_flush_addr_o;
@ -201,7 +202,8 @@ module tinyriscv_core #(
.mepc_o(csr_mepc_o), .mepc_o(csr_mepc_o),
.mstatus_o(csr_mstatus_o), .mstatus_o(csr_mstatus_o),
.mie_o(csr_mie_o), .mie_o(csr_mie_o),
.dpc_o(csr_dpc_o) .dpc_o(csr_dpc_o),
.dcsr_o(csr_dcsr_o)
); );
ifu_idu u_ifu_idu( ifu_idu u_ifu_idu(
@ -319,6 +321,7 @@ module tinyriscv_core #(
.mstatus_i(csr_mstatus_o), .mstatus_i(csr_mstatus_o),
.mie_i(csr_mie_o), .mie_i(csr_mie_o),
.dpc_i(csr_dpc_o), .dpc_i(csr_dpc_o),
.dcsr_i(csr_dcsr_o),
.irq_software_i(irq_software_i), .irq_software_i(irq_software_i),
.irq_timer_i(irq_timer_i), .irq_timer_i(irq_timer_i),
.irq_external_i(irq_external_i), .irq_external_i(irq_external_i),

View File

@ -17,11 +17,14 @@
`define DbgVersion013 4'h2 `define DbgVersion013 4'h2
`define ProgBufSize 5'h8 `define ProgBufSize 5'h8
`define DataCount 4'h2 `define DataCount 4'h1
`define HaltAddress 64'h800 `define HaltAddress 64'h800
`define ResumeAddress `HaltAddress + 4 `define ResumeAddress `HaltAddress + 4
`define ExceptionAddress `HaltAddress + 8 `define ExceptionAddress `HaltAddress + 8
`define DataAddr 12'h380 `define DataBaseAddr 12'h380
`define AbstCmdBaseAddr 12'h338
`define AbstCmdCount 12'd10
`define ProgbufBaseAddr `AbstCmdBaseAddr + (4 * `AbstCmdCount)
// dmi op // dmi op
`define DMI_OP_NOP 2'b00 `define DMI_OP_NOP 2'b00
@ -33,11 +36,13 @@
`define Data1 6'h05 `define Data1 6'h05
`define Data2 6'h06 `define Data2 6'h06
`define Data3 6'h07 `define Data3 6'h07
`define Data4 6'h08
`define DMControl 6'h10 `define DMControl 6'h10
`define DMStatus 6'h11 `define DMStatus 6'h11
`define Hartinfo 6'h12 `define Hartinfo 6'h12
`define AbstractCS 6'h16 `define AbstractCS 6'h16
`define Command 6'h17 `define Command 6'h17
`define AbstractAuto 8'h18
`define ProgBuf0 6'h20 `define ProgBuf0 6'h20
`define ProgBuf1 6'h21 `define ProgBuf1 6'h21
`define ProgBuf2 6'h22 `define ProgBuf2 6'h22
@ -128,3 +133,21 @@
`define Sbaccess16 1 `define Sbaccess16 1
`define Sbaccess8 0 `define Sbaccess8 0
// abstractauto
`define AutoexecData 11:0
`define AutoexecProgbuf 31:16
`define CSR_CYCLE 12'hc00
`define CSR_CYCLEH 12'hc80
`define CSR_MTVEC 12'h305
`define CSR_MCAUSE 12'h342
`define CSR_MEPC 12'h341
`define CSR_MIE 12'h304
`define CSR_MSTATUS 12'h300
`define CSR_MSCRATCH 12'h340
`define CSR_MHARTID 12'hF14
`define CSR_DCSR 12'h7b0
`define CSR_DPC 12'h7b1
`define CSR_DSCRATCH0 12'h7b2
`define CSR_DSCRATCH1 12'h7b3

View File

@ -20,8 +20,8 @@ module jtag_dm #(
parameter DMI_ADDR_BITS = 6, parameter DMI_ADDR_BITS = 6,
parameter DMI_DATA_BITS = 32, parameter DMI_DATA_BITS = 32,
parameter DMI_OP_BITS = 2, parameter DMI_OP_BITS = 2,
localparam DMI_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS, parameter DMI_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS,
localparam DMI_RESP_BITS = DMI_REQ_BITS parameter DMI_RESP_BITS = DMI_REQ_BITS
)( )(
input wire clk, input wire clk,
@ -39,6 +39,7 @@ module jtag_dm #(
output wire debug_req_o, output wire debug_req_o,
output wire ndmreset_o, output wire ndmreset_o,
output wire halted_o,
// jtag access mem devices(DM as master) // jtag access mem devices(DM as master)
output wire master_req_o, output wire master_req_o,
@ -61,7 +62,10 @@ module jtag_dm #(
); );
localparam HARTINFO = {8'h0, 4'h2, 3'b0, 1'b1, `DataCount, `DataAddr}; localparam HARTINFO = {8'h0, 4'h2, 3'b0, 1'b1, `DataCount, `DataBaseAddr};
localparam CmdErrorNone = 3'h0;
localparam CmdErrorBusy = 3'h1;
wire halted; wire halted;
wire resumeack; wire resumeack;
@ -77,7 +81,11 @@ module jtag_dm #(
reg sbdata_write_valid; reg sbdata_write_valid;
reg sbdata_read_valid; reg sbdata_read_valid;
reg[31:0] sbcs; reg[31:0] sbcs;
reg[31:0] a_abstractcs;
reg[31:0] dm_resp_data_d, dm_resp_data_q; reg[31:0] dm_resp_data_d, dm_resp_data_q;
reg cmd_valid_d, cmd_valid_q;
reg[15:0] abstractautoprogbuf;
reg[3:0] progbuf_index;
wire[31:0] sba_sbaddress; wire[31:0] sba_sbaddress;
wire[31:0] dm_sbaddress; wire[31:0] dm_sbaddress;
wire resumereq; wire resumereq;
@ -85,17 +93,23 @@ module jtag_dm #(
wire sbdata_valid; wire sbdata_valid;
wire[31:0] sbdata; wire[31:0] sbdata;
wire[19:0] hartsel; wire[19:0] hartsel;
wire data_valid;
wire[31:0] data0;
wire cmderror_valid;
wire[2:0] cmderror;
// DM regs // DM regs
reg[31:0] dmstatus; reg[31:0] dmstatus;
reg[31:0] dmcontrol_d, dmcontrol_q; reg[31:0] dmcontrol_d, dmcontrol_q;
reg[31:0] abstractcs; reg[31:0] abstractcs;
reg[31:0] abstractauto_d, abstractauto_q;
reg[31:0] sbcs_d, sbcs_q; reg[31:0] sbcs_d, sbcs_q;
reg[31:0] sbdata0_d, sbdata0_q; reg[31:0] sbdata0_d, sbdata0_q;
reg[31:0] sbaddress0_d, sbaddress0_q; reg[31:0] sbaddress0_d, sbaddress0_q;
reg[31:0] command_d, command_q; reg[31:0] command_d, command_q;
reg[31:0] data0_d, data0_q; reg[31:0] data0_d, data0_q;
reg[2:0] cmderr_d, cmderr_q; reg[2:0] cmderr_d, cmderr_q;
reg[`ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
assign dm_sbaddress = sbaddress0_q; assign dm_sbaddress = sbaddress0_q;
@ -176,6 +190,8 @@ module jtag_dm #(
abstractcs[`Progbufsize] = `ProgBufSize; abstractcs[`Progbufsize] = `ProgBufSize;
abstractcs[`Busy] = cmdbusy; abstractcs[`Busy] = cmdbusy;
abstractcs[`Cmderr] = cmderr_q; abstractcs[`Cmderr] = cmderr_q;
a_abstractcs = 32'h0;
abstractauto_d = abstractauto_q;
havereset_d = havereset_q; havereset_d = havereset_q;
sbaddress0_d = sba_sbaddress; sbaddress0_d = sba_sbaddress;
@ -185,6 +201,12 @@ module jtag_dm #(
sbdata_write_valid = 1'b0; sbdata_write_valid = 1'b0;
sbdata_read_valid = 1'b0; sbdata_read_valid = 1'b0;
sbcs = 32'h0; sbcs = 32'h0;
command_d = command_q;
cmd_valid_d = 1'b0;
progbuf_index = 4'h0;
progbuf_d = progbuf_q;
abstractautoprogbuf = abstractauto_q[`AutoexecProgbuf];
data0_d = data0_q; data0_d = data0_q;
sbcs_d = sbcs_q; sbcs_d = sbcs_q;
@ -200,6 +222,8 @@ module jtag_dm #(
`Hartinfo :dm_resp_data_d = HARTINFO; `Hartinfo :dm_resp_data_d = HARTINFO;
`SBCS :dm_resp_data_d = sbcs_q; `SBCS :dm_resp_data_d = sbcs_q;
`AbstractCS:dm_resp_data_d = abstractcs; `AbstractCS:dm_resp_data_d = abstractcs;
`AbstractAuto: dm_resp_data_d = abstractauto_q;
`Command :dm_resp_data_d = 32'h0;
`SBAddress0:dm_resp_data_d = sbaddress0_q; `SBAddress0:dm_resp_data_d = sbaddress0_q;
`SBData0 : begin `SBData0 : begin
if (sbbusy || sbcs_q[`Sbbusyerror]) begin if (sbbusy || sbcs_q[`Sbbusyerror]) begin
@ -209,7 +233,26 @@ module jtag_dm #(
dm_resp_data_d = sbdata0_q; dm_resp_data_d = sbdata0_q;
end end
end end
default:; `Data0: begin
dm_resp_data_d = data0_q;
if (!cmdbusy) begin
cmd_valid_d = abstractauto_q[0];
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end
`ProgBuf0, `ProgBuf1, `ProgBuf2, `ProgBuf3,
`ProgBuf4, `ProgBuf5, `ProgBuf6, `ProgBuf7,
`ProgBuf8, `ProgBuf9: begin
progbuf_index = dm_op_addr[3:0];
dm_resp_data_d = progbuf_q[progbuf_index];
if (!cmdbusy) begin
cmd_valid_d = abstractautoprogbuf[progbuf_index];
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end
default: dm_resp_data_d = 32'h0;
endcase endcase
// write // write
end else if (dm_op == `DMI_OP_WRITE) begin end else if (dm_op == `DMI_OP_WRITE) begin
@ -222,7 +265,12 @@ module jtag_dm #(
end end
`Data0: begin `Data0: begin
if (!cmdbusy) begin
data0_d = dm_op_data; data0_d = dm_op_data;
cmd_valid_d = abstractauto_q[0];
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end end
`SBCS: begin `SBCS: begin
@ -255,8 +303,44 @@ module jtag_dm #(
end end
end end
`AbstractCS: begin `Command: begin
if (!cmdbusy) begin
cmd_valid_d = 1'b1;
command_d = dm_op_data;
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end
`AbstractCS: begin
a_abstractcs = dm_op_data;
if (!cmdbusy) begin
cmderr_d = (~a_abstractcs[`Cmderr]) & cmderr_q;
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end
`AbstractAuto: begin
if (!cmdbusy) begin
abstractauto_d = 32'h0;
abstractauto_d[`AutoexecData] = {11'h0, dm_op_data[0]};
abstractauto_d[`AutoexecProgbuf] = dm_op_data[`ProgBufSize-1+16:16];
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end
`ProgBuf0, `ProgBuf1, `ProgBuf2, `ProgBuf3,
`ProgBuf4, `ProgBuf5, `ProgBuf6, `ProgBuf7,
`ProgBuf8, `ProgBuf9: begin
if (!cmdbusy) begin
progbuf_index = dm_op_addr[3:0];
progbuf_d[progbuf_index] = dm_op_data;
cmd_valid_d = abstractautoprogbuf[progbuf_index];
end else if (cmderr_q == CmdErrorNone) begin
cmderr_d = CmdErrorBusy;
end
end end
default:; default:;
@ -297,17 +381,42 @@ module jtag_dm #(
sbdata0_d = sbdata; sbdata0_d = sbdata;
end end
if (cmderror_valid) begin
cmderr_d = cmderror;
end
if (data_valid) begin
data0_d = data0;
end
// set the havereset flag when we did a ndmreset // set the havereset flag when we did a ndmreset
if (ndmreset_o) begin if (ndmreset_o) begin
havereset_d = 1'b1; havereset_d = 1'b1;
end end
end end
assign debug_req_o = dmcontrol_q[`Haltreq]; assign debug_req_o = dmcontrol_q[`Haltreq];
assign ndmreset_o = dmcontrol_q[`Ndmreset]; assign ndmreset_o = dmcontrol_q[`Ndmreset];
assign resumereq = dmcontrol_q[`Resumereq]; assign resumereq = dmcontrol_q[`Resumereq];
assign halted_o = halted;
genvar i;
generate
for (i = 0; i < `ProgBufSize; i = i + 1) begin: gen_progbuf
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
progbuf_q[i] <= 32'h0;
end else begin
if (!dmcontrol_q[`Dmactive]) begin
progbuf_q[i] <= 32'h0;
end else begin
progbuf_q[i] <= progbuf_d[i];
end
end
end
end
endgenerate
always @ (posedge clk or negedge rst_n) begin always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin if (!rst_n) begin
@ -319,6 +428,9 @@ module jtag_dm #(
sbdata0_q <= 32'h0; sbdata0_q <= 32'h0;
dm_resp_data_q <= 32'h0; dm_resp_data_q <= 32'h0;
cmderr_q <= 3'h0; cmderr_q <= 3'h0;
command_q <= 32'h0;
abstractauto_q <= 32'h0;
cmd_valid_q <= 1'b0;
end else begin end else begin
if (!dmcontrol_q[`Dmactive]) begin if (!dmcontrol_q[`Dmactive]) begin
dmcontrol_q[`Haltreq] <= 1'b0; dmcontrol_q[`Haltreq] <= 1'b0;
@ -338,6 +450,9 @@ module jtag_dm #(
sbdata0_q <= 32'h0; sbdata0_q <= 32'h0;
dm_resp_data_q <= 32'h0; dm_resp_data_q <= 32'h0;
cmderr_q <= 3'h0; cmderr_q <= 3'h0;
command_q <= 32'h0;
abstractauto_q <= 32'h0;
cmd_valid_q <= 1'b0;
end else begin end else begin
dmcontrol_q <= dmcontrol_d; dmcontrol_q <= dmcontrol_d;
data0_q <= data0_d; data0_q <= data0_d;
@ -346,14 +461,15 @@ module jtag_dm #(
sbdata0_q <= sbdata0_d; sbdata0_q <= sbdata0_d;
dm_resp_data_q <= dm_resp_data_d; dm_resp_data_q <= dm_resp_data_d;
cmderr_q <= cmderr_d; cmderr_q <= cmderr_d;
command_q <= command_d;
abstractauto_q <= abstractauto_d;
cmd_valid_q <= cmd_valid_d;
end end
havereset_q <= havereset_d; havereset_q <= havereset_d;
end end
end end
jtag_mem #( jtag_mem u_jtag_mem (
) u_jtag_mem (
.clk(clk), .clk(clk),
.rst_n(rst_n), .rst_n(rst_n),
@ -362,6 +478,15 @@ module jtag_dm #(
.clear_resumeack_i(clear_resumeack), .clear_resumeack_i(clear_resumeack),
.resumereq_i(resumereq), .resumereq_i(resumereq),
.haltreq_i(debug_req_o), .haltreq_i(debug_req_o),
.progbuf_i(),
.data_i(data0_q),
.data_o(data0),
.data_valid_o(data_valid),
.cmd_valid_i(cmd_valid_q),
.cmd_i(command_q),
.cmderror_valid_o(cmderror_valid),
.cmderror_o(cmderror),
.cmdbusy_o(cmdbusy), .cmdbusy_o(cmdbusy),
.req_i(slave_req_i), .req_i(slave_req_i),
@ -372,9 +497,7 @@ module jtag_dm #(
.rdata_o(slave_rdata_o) .rdata_o(slave_rdata_o)
); );
jtag_sba #( jtag_sba u_jtag_sba (
) u_jtag_sba (
.clk(clk), .clk(clk),
.rst_n(rst_n), .rst_n(rst_n),
.sbaddress_i(sbaddress0_q), .sbaddress_i(sbaddress0_q),

View File

@ -1,290 +0,0 @@
/*
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 jtag_driver #(
parameter DMI_ADDR_BITS = 6,
parameter DMI_DATA_BITS = 32,
parameter DMI_OP_BITS = 2)(
rst_n,
jtag_TCK,
jtag_TDI,
jtag_TMS,
jtag_TDO,
// rx
dm_resp_i,
dm_resp_data_i,
dtm_ack_o,
// tx
dm_ack_i,
dtm_req_valid_o,
dtm_req_data_o
);
parameter IDCODE_VERSION = 4'h1;
parameter IDCODE_PART_NUMBER = 16'he200;
parameter IDCODE_MANUFLD = 11'h537;
parameter DTM_VERSION = 4'h1;
parameter IR_BITS = 5;
parameter DM_RESP_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS;
parameter DTM_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS;
parameter SHIFT_REG_BITS = DTM_REQ_BITS;
// input and output
input wire rst_n;
input wire jtag_TCK;
input wire jtag_TDI;
input wire jtag_TMS;
output reg jtag_TDO;
input wire dm_resp_i;
input wire[DM_RESP_BITS - 1:0] dm_resp_data_i;
output wire dtm_ack_o;
input wire dm_ack_i;
output wire dtm_req_valid_o;
output wire[DTM_REQ_BITS - 1:0] dtm_req_data_o;
// JTAG StateMachine
parameter TEST_LOGIC_RESET = 4'h0;
parameter RUN_TEST_IDLE = 4'h1;
parameter SELECT_DR = 4'h2;
parameter CAPTURE_DR = 4'h3;
parameter SHIFT_DR = 4'h4;
parameter EXIT1_DR = 4'h5;
parameter PAUSE_DR = 4'h6;
parameter EXIT2_DR = 4'h7;
parameter UPDATE_DR = 4'h8;
parameter SELECT_IR = 4'h9;
parameter CAPTURE_IR = 4'hA;
parameter SHIFT_IR = 4'hB;
parameter EXIT1_IR = 4'hC;
parameter PAUSE_IR = 4'hD;
parameter EXIT2_IR = 4'hE;
parameter UPDATE_IR = 4'hF;
// DTM regs
parameter REG_BYPASS = 5'b11111;
parameter REG_IDCODE = 5'b00001;
parameter REG_DMI = 5'b10001;
parameter REG_DTMCS = 5'b10000;
reg[IR_BITS - 1:0] ir_reg;
reg[SHIFT_REG_BITS - 1:0] shift_reg;
reg[3:0] jtag_state;
wire is_busy;
reg sticky_busy;
reg dtm_req_valid;
reg[DTM_REQ_BITS - 1:0] dtm_req_data;
reg[DM_RESP_BITS - 1:0] dm_resp_data;
reg dm_is_busy;
wire[5:0] addr_bits = DMI_ADDR_BITS[5:0];
wire [SHIFT_REG_BITS - 1:0] busy_response;
wire [SHIFT_REG_BITS - 1:0] none_busy_response;
wire[31:0] idcode;
wire[31:0] dtmcs;
wire[1:0] dmi_stat;
wire dtm_reset;
wire tx_idle;
wire rx_valid;
wire[DM_RESP_BITS - 1:0] rx_data;
wire tx_valid;
wire[DTM_REQ_BITS - 1:0] tx_data;
assign dtm_reset = shift_reg[16];
assign idcode = {IDCODE_VERSION, IDCODE_PART_NUMBER, IDCODE_MANUFLD, 1'h1};
assign dtmcs = {14'b0,
1'b0, // dmihardreset
1'b0, // dmireset
1'b0,
3'h5, // idle
dmi_stat, // dmistat
addr_bits, // abits
DTM_VERSION}; // version
assign busy_response = {{(DMI_ADDR_BITS + DMI_DATA_BITS){1'b0}}, {(DMI_OP_BITS){1'b1}}}; // op = 2'b11
assign none_busy_response = dm_resp_data;
assign is_busy = sticky_busy | dm_is_busy;
assign dmi_stat = is_busy ? 2'b01 : 2'b00;
// state switch
always @(posedge jtag_TCK or negedge rst_n) begin
if (!rst_n) begin
jtag_state <= TEST_LOGIC_RESET;
end else begin
case (jtag_state)
TEST_LOGIC_RESET : jtag_state <= jtag_TMS ? TEST_LOGIC_RESET : RUN_TEST_IDLE;
RUN_TEST_IDLE : jtag_state <= jtag_TMS ? SELECT_DR : RUN_TEST_IDLE;
SELECT_DR : jtag_state <= jtag_TMS ? SELECT_IR : CAPTURE_DR;
CAPTURE_DR : jtag_state <= jtag_TMS ? EXIT1_DR : SHIFT_DR;
SHIFT_DR : jtag_state <= jtag_TMS ? EXIT1_DR : SHIFT_DR;
EXIT1_DR : jtag_state <= jtag_TMS ? UPDATE_DR : PAUSE_DR;
PAUSE_DR : jtag_state <= jtag_TMS ? EXIT2_DR : PAUSE_DR;
EXIT2_DR : jtag_state <= jtag_TMS ? UPDATE_DR : SHIFT_DR;
UPDATE_DR : jtag_state <= jtag_TMS ? SELECT_DR : RUN_TEST_IDLE;
SELECT_IR : jtag_state <= jtag_TMS ? TEST_LOGIC_RESET : CAPTURE_IR;
CAPTURE_IR : jtag_state <= jtag_TMS ? EXIT1_IR : SHIFT_IR;
SHIFT_IR : jtag_state <= jtag_TMS ? EXIT1_IR : SHIFT_IR;
EXIT1_IR : jtag_state <= jtag_TMS ? UPDATE_IR : PAUSE_IR;
PAUSE_IR : jtag_state <= jtag_TMS ? EXIT2_IR : PAUSE_IR;
EXIT2_IR : jtag_state <= jtag_TMS ? UPDATE_IR : SHIFT_IR;
UPDATE_IR : jtag_state <= jtag_TMS ? SELECT_DR : RUN_TEST_IDLE;
endcase
end
end
// IR or DR shift
always @(posedge jtag_TCK) begin
case (jtag_state)
// IR
CAPTURE_IR: shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}}, 1'b1}; //JTAG spec says it must be b01
SHIFT_IR : shift_reg <= {{(SHIFT_REG_BITS - IR_BITS){1'b0}}, jtag_TDI, shift_reg[IR_BITS - 1:1]}; // right shift 1 bit
// DR
CAPTURE_DR: case (ir_reg)
REG_BYPASS : shift_reg <= {(SHIFT_REG_BITS){1'b0}};
REG_IDCODE : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, idcode};
REG_DTMCS : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, dtmcs};
REG_DMI : shift_reg <= is_busy ? busy_response : none_busy_response;
default:
shift_reg <= {(SHIFT_REG_BITS){1'b0}};
endcase
SHIFT_DR : case (ir_reg)
REG_BYPASS : shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}}, jtag_TDI}; // in = out
REG_IDCODE : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, jtag_TDI, shift_reg[31:1]}; // right shift 1 bit
REG_DTMCS : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, jtag_TDI, shift_reg[31:1]}; // right shift 1 bit
REG_DMI : shift_reg <= {jtag_TDI, shift_reg[SHIFT_REG_BITS - 1:1]}; // right shift 1 bit
default:
shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}} , jtag_TDI};
endcase
endcase
end
// start access DM module
always @(posedge jtag_TCK or negedge rst_n) begin
if (!rst_n) begin
dtm_req_valid <= 1'b0;
dtm_req_data <= {DTM_REQ_BITS{1'b0}};
end else begin
if (jtag_state == UPDATE_DR) begin
if (ir_reg == REG_DMI) begin
// if DM can be access
if (!is_busy & tx_idle) begin
dtm_req_valid <= 1'b1;
dtm_req_data <= shift_reg;
end
end
end else begin
dtm_req_valid <= 1'b0;
end
end
end
assign tx_valid = dtm_req_valid;
assign tx_data = dtm_req_data;
// DTM reset
always @ (posedge jtag_TCK or negedge rst_n) begin
if (!rst_n) begin
sticky_busy <= 1'b0;
end else begin
if (jtag_state == UPDATE_DR) begin
if (ir_reg == REG_DTMCS & dtm_reset) begin
sticky_busy <= 1'b0;
end
end else if (jtag_state == CAPTURE_DR) begin
if (ir_reg == REG_DMI) begin
sticky_busy <= is_busy;
end
end
end
end
// receive DM response data
always @ (posedge jtag_TCK or negedge rst_n) begin
if (!rst_n) begin
dm_resp_data <= {DM_RESP_BITS{1'b0}};
end else begin
if (rx_valid) begin
dm_resp_data <= rx_data;
end
end
end
// tx busy
always @ (posedge jtag_TCK or negedge rst_n) begin
if (!rst_n) begin
dm_is_busy <= 1'b0;
end else begin
if (dtm_req_valid) begin
dm_is_busy <= 1'b1;
end else if (rx_valid) begin
dm_is_busy <= 1'b0;
end
end
end
// TAP reset
always @(negedge jtag_TCK) begin
if (jtag_state == TEST_LOGIC_RESET) begin
ir_reg <= REG_IDCODE;
end else if (jtag_state == UPDATE_IR) begin
ir_reg <= shift_reg[IR_BITS - 1:0];
end
end
// TDO output
always @(negedge jtag_TCK) begin
if (jtag_state == SHIFT_IR) begin
jtag_TDO <= shift_reg[0];
end else if (jtag_state == SHIFT_DR) begin
jtag_TDO <= shift_reg[0];
end else begin
jtag_TDO <= 1'b0;
end
end
full_handshake_tx #(
.DW(DTM_REQ_BITS)
) tx(
.clk(jtag_TCK),
.rst_n(rst_n),
.ack_i(dm_ack_i),
.req_i(tx_valid),
.req_data_i(tx_data),
.idle_o(tx_idle),
.req_o(dtm_req_valid_o),
.req_data_o(dtm_req_data_o)
);
full_handshake_rx #(
.DW(DM_RESP_BITS)
) rx(
.clk(jtag_TCK),
.rst_n(rst_n),
.req_i(dm_resp_i),
.req_data_i(dm_resp_data_i),
.ack_o(dtm_ack_o),
.recv_data_o(rx_data),
.recv_rdy_o(rx_valid)
);
endmodule

View File

@ -20,10 +20,10 @@ module jtag_dtm #(
parameter DMI_ADDR_BITS = 6, parameter DMI_ADDR_BITS = 6,
parameter DMI_DATA_BITS = 32, parameter DMI_DATA_BITS = 32,
parameter DMI_OP_BITS = 2, parameter DMI_OP_BITS = 2,
localparam TAP_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS, parameter TAP_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS,
localparam DTM_RESP_BITS = TAP_REQ_BITS, parameter DTM_RESP_BITS = TAP_REQ_BITS,
localparam DTM_REQ_BITS = DTM_RESP_BITS, parameter DTM_REQ_BITS = DTM_RESP_BITS,
localparam DMI_RESP_BITS = DTM_REQ_BITS parameter DMI_RESP_BITS = DTM_REQ_BITS
)( )(
input wire jtag_tck_i, // JTAG test clock pad input wire jtag_tck_i, // JTAG test clock pad

View File

@ -14,21 +14,29 @@
limitations under the License. limitations under the License.
*/ */
`include "jtag_def.sv"
module jtag_mem(
module jtag_mem #(
)(
input wire clk, input wire clk,
input wire rst_n, input wire rst_n,
output wire halted_o, output wire halted_o,
output wire resumeack_o, output wire resumeack_o,
output wire cmdbusy_o,
input wire clear_resumeack_i, input wire clear_resumeack_i,
input wire resumereq_i, input wire resumereq_i,
input wire haltreq_i, input wire haltreq_i,
input wire [`ProgBufSize-1:0][31:0] progbuf_i,
input wire [31:0] data_i,
output wire [31:0] data_o,
output wire data_valid_o,
input wire cmd_valid_i,
input wire [31:0] cmd_i,
output wire cmderror_valid_o,
output wire [2:0] cmderror_o,
output wire cmdbusy_o,
input wire req_i, input wire req_i,
input wire we_i, input wire we_i,
input wire [31:0] addr_i, input wire [31:0] addr_i,
@ -43,12 +51,33 @@ module jtag_mem #(
// x10/a0 // x10/a0
localparam LoadBaseAddr = 5'd10; localparam LoadBaseAddr = 5'd10;
localparam DataBaseAddr = `DataAddr; localparam Data0Addr = `DataBaseAddr;
localparam DataEndAddr = (`DataAddr + 4 * `DataCount - 1); localparam Data1Addr = `DataBaseAddr + 4;
localparam ProgBufBaseAddr = (`DataAddr - 4 * `ProgBufSize); localparam Data2Addr = `DataBaseAddr + 8;
localparam ProgBufEndAddr = (`DataAddr - 1); localparam Data3Addr = `DataBaseAddr + 12;
localparam AbstractCmdBaseAddr = (ProgBufBaseAddr - 4 * 10); localparam Data4Addr = `DataBaseAddr + 16;
localparam AbstractCmdEndAddr = (ProgBufBaseAddr - 1);
localparam Progbuf0Addr = `ProgbufBaseAddr;
localparam Progbuf1Addr = `ProgbufBaseAddr + 4;
localparam Progbuf2Addr = `ProgbufBaseAddr + 8;
localparam Progbuf3Addr = `ProgbufBaseAddr + 12;
localparam Progbuf4Addr = `ProgbufBaseAddr + 16;
localparam Progbuf5Addr = `ProgbufBaseAddr + 20;
localparam Progbuf6Addr = `ProgbufBaseAddr + 24;
localparam Progbuf7Addr = `ProgbufBaseAddr + 28;
localparam Progbuf8Addr = `ProgbufBaseAddr + 32;
localparam Progbuf9Addr = `ProgbufBaseAddr + 36;
localparam AbstractCmd0Addr = `AbstCmdBaseAddr;
localparam AbstractCmd1Addr = `AbstCmdBaseAddr + 4;
localparam AbstractCmd2Addr = `AbstCmdBaseAddr + 8;
localparam AbstractCmd3Addr = `AbstCmdBaseAddr + 12;
localparam AbstractCmd4Addr = `AbstCmdBaseAddr + 16;
localparam AbstractCmd5Addr = `AbstCmdBaseAddr + 20;
localparam AbstractCmd6Addr = `AbstCmdBaseAddr + 24;
localparam AbstractCmd7Addr = `AbstCmdBaseAddr + 28;
localparam AbstractCmd8Addr = `AbstCmdBaseAddr + 32;
localparam AbstractCmd9Addr = `AbstCmdBaseAddr + 36;
localparam WhereToAddr = 12'h300; localparam WhereToAddr = 12'h300;
localparam FlagsBaseAddr = 12'h400; localparam FlagsBaseAddr = 12'h400;
@ -59,23 +88,114 @@ module jtag_mem #(
localparam ResumingAddr = 12'h108; localparam ResumingAddr = 12'h108;
localparam ExceptionAddr = 12'h10C; localparam ExceptionAddr = 12'h10C;
localparam CmdAccessRegister = 8'h0;
localparam CmdQuickAccess = 8'h1;
localparam CmdAccessMemory = 8'h2;
localparam CmdErrorNone = 3'h0;
localparam CmdErrorHaltResume = 3'h4;
localparam CmdErrorNotSupport = 3'h2;
localparam CmdErrorException = 3'h3;
localparam illegal = 32'h00000000;
localparam nop = 32'h00000013;
localparam ebreak = 32'h00100073;
localparam S_IDLE = 4'b0001; localparam S_IDLE = 4'b0001;
localparam S_RESUME = 4'b0010; localparam S_RESUME = 4'b0010;
localparam S_GO = 4'b0100; localparam S_GO = 4'b0100;
localparam S_CMD_EXECUTING = 4'b1000; localparam S_CMD_EXECUTING = 4'b1000;
reg[3:0] state_d, state_q;
function automatic [31:0] jal;
input [4:0] rd;
input [20:0] imm;
jal = {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
endfunction
function automatic [31:0] slli;
input [4:0] rd;
input [4:0] rs1;
input [5:0] shamt;
slli = {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
endfunction
function automatic [31:0] srli;
input [4:0] rd;
input [4:0] rs1;
input [5:0] shamt;
srli = {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
endfunction
function automatic [31:0] load;
input [2:0] size;
input [4:0] dest;
input [4:0] base;
input [11:0] offset;
load = {offset[11:0], base, size, dest, 7'h03};
endfunction
function automatic [31:0] auipc;
input [4:0] rd;
input [20:0] imm;
auipc = {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
endfunction
function automatic [31:0] store;
input [2:0] size;
input [4:0] src;
input [4:0] base;
input [11:0] offset;
store = {offset[11:5], src, base, size, offset[4:0], 7'h23};
endfunction
function automatic [31:0] csrw;
input [11:0] csr;
input [4:0] rs1;
csrw = {csr, rs1, 3'h1, 5'h0, 7'h73};
endfunction
function automatic [31:0] csrr;
input [11:0] csr;
input [4:0] dest;
csrr = {csr, 5'h0, 3'h2, dest, 7'h73};
endfunction
reg[3:0] state_d, state_q;
reg[31:0] rdata_d, rdata_q; reg[31:0] rdata_d, rdata_q;
reg halted_d, halted_q; reg halted_d, halted_q;
reg resuming_d, resuming_q; reg resuming_d, resuming_q;
reg resume, go, going; reg resume, go, going;
reg fwd_rom_q; reg fwd_rom_q;
reg word_enable32_q; reg word_enable32_q;
reg data_valid;
reg cmdbusy;
wire fwd_rom_d; wire fwd_rom_d;
wire[63:0] rom_rdata; wire[63:0] rom_rdata;
reg[31:0] data_bits;
reg[9:0][31:0] abstract_cmd;
reg unsupported_command;
reg cmderror_valid;
reg[2:0] cmderror;
reg exception;
wire[11:0] progbuf_baseaddr = Progbuf0Addr;
wire[11:0] abstractcmd_baseaddr = AbstractCmd0Addr;
wire[7:0] cmd_type = cmd_i[31:24];
wire cmd_postexec = cmd_i[18];
wire cmd_transfer = cmd_i[17];
wire cmd_write = cmd_i[16];
wire[15:0] cmd_regno = cmd_i[15:0];
wire[2:0] cmd_aarsize = cmd_i[22:20];
wire cmd_aarpostincrement = cmd_i[19];
// word mux for 32bit and 64bit buses // word mux for 32bit and 64bit buses
wire [63:0] word_mux; wire [63:0] word_mux;
@ -84,38 +204,84 @@ module jtag_mem #(
assign halted_o = halted_q; assign halted_o = halted_q;
assign resumeack_o = resuming_q; assign resumeack_o = resuming_q;
assign cmdbusy_o = 1'b0;
always @ (*) begin always @ (*) begin
state_d = state_q; state_d = state_q;
resume = 1'b0; resume = 1'b0;
go = 1'b0; go = 1'b0;
cmdbusy = 1'b1;
cmderror_valid = 1'b0;
cmderror = CmdErrorNone;
case (state_q) case (state_q)
S_IDLE: begin S_IDLE: begin
cmdbusy = 1'b0;
if (resumereq_i && (!resuming_q) && if (resumereq_i && (!resuming_q) &&
halted_q && (!haltreq_i)) begin halted_q && (!haltreq_i)) begin
state_d = S_RESUME; state_d = S_RESUME;
end end
if (cmd_valid_i) begin
if (!halted_q) begin
cmderror_valid = 1'b1;
cmderror = CmdErrorHaltResume;
end else if (unsupported_command) begin
cmderror_valid = 1'b1;
cmderror = CmdErrorNotSupport;
end else begin
state_d = S_GO;
end
end
end
S_GO: begin
cmdbusy = 1'b1;
go = 1'b1;
if (going) begin
state_d = S_CMD_EXECUTING;
end
end end
S_RESUME: begin S_RESUME: begin
resume = 1'b1; resume = 1'b1;
cmdbusy = 1'b1;
if (resuming_q) begin if (resuming_q) begin
state_d = S_IDLE; state_d = S_IDLE;
end end
end end
S_CMD_EXECUTING: begin
cmdbusy = 1'b1;
go = 1'b0;
if (halted_q) begin
state_d = S_IDLE;
end
end
default:; default:;
endcase endcase
if (exception) begin
cmderror_valid = 1'b1;
cmderror = CmdErrorException;
end end
end
assign cmderror_valid_o = cmderror_valid;
assign cmderror_o = cmderror;
assign cmdbusy_o = cmdbusy;
always @ (*) begin always @ (*) begin
rdata_d = rdata_q; rdata_d = rdata_q;
halted_d = halted_q; halted_d = halted_q;
resuming_d = resuming_q; resuming_d = resuming_q;
going = 1'b0;
exception = 1'b0;
data_valid = 1'b0;
data_bits = data_i;
if (clear_resumeack_i) begin if (clear_resumeack_i) begin
resuming_d = 1'b0; resuming_d = 1'b0;
end end
@ -128,7 +294,7 @@ module jtag_mem #(
end end
GoingAddr: begin GoingAddr: begin
going = 1'b1;
end end
ResumingAddr: begin ResumingAddr: begin
@ -137,7 +303,20 @@ module jtag_mem #(
end end
ExceptionAddr: begin ExceptionAddr: begin
exception = 1'b1;
end
Data0Addr, Data1Addr, Data2Addr,
Data3Addr, Data4Addr: begin
data_valid = 1'b1;
if (be_i[0])
data_bits[7:0] = wdata_i[7:0];
if (be_i[1])
data_bits[15:8] = wdata_i[15:8];
if (be_i[2])
data_bits[23:16] = wdata_i[23:16];
if (be_i[3])
data_bits[31:24] = wdata_i[31:24];
end end
default:; default:;
@ -145,14 +324,144 @@ module jtag_mem #(
// read // read
end else begin end else begin
case (addr_i[DbgAddressBits-1:0]) case (addr_i[DbgAddressBits-1:0])
WhereToAddr: begin
if (cmdbusy & (cmd_type == CmdAccessRegister)) begin
// execute program buf
if (cmd_postexec) begin
rdata_d = jal(5'h0, {9'h0, progbuf_baseaddr-WhereToAddr});
// execute command
end else begin
rdata_d = jal(5'h0, {9'h0, abstractcmd_baseaddr-WhereToAddr});
end
end
end
// harts are polling for flags here // harts are polling for flags here
FlagsBaseAddr: begin FlagsBaseAddr: begin
rdata_d = {30'b0, resume, go}; rdata_d = {30'b0, resume, go};
end end
Data0Addr, Data1Addr, Data2Addr, Data3Addr,
Data4Addr: begin
rdata_d = data_i;
end
Progbuf0Addr, Progbuf1Addr, Progbuf2Addr, Progbuf3Addr,
Progbuf4Addr, Progbuf5Addr, Progbuf6Addr, Progbuf7Addr,
Progbuf8Addr, Progbuf9Addr: begin
rdata_d = progbuf_i[addr_i[DbgAddressBits-1:3] -
progbuf_baseaddr[DbgAddressBits-1:3]];
end
AbstractCmd0Addr, AbstractCmd1Addr, AbstractCmd2Addr, AbstractCmd3Addr,
AbstractCmd4Addr, AbstractCmd5Addr, AbstractCmd6Addr, AbstractCmd7Addr,
AbstractCmd8Addr, AbstractCmd9Addr: begin
rdata_d = abstract_cmd[addr_i[DbgAddressBits-1:3] -
abstractcmd_baseaddr[DbgAddressBits-1:3]];
end
default:; default:;
endcase endcase
end end
end
assign data_valid_o = data_valid;
assign data_o = data_bits;
always @ (*) begin
unsupported_command = 1'b0;
abstract_cmd[0] = illegal;
abstract_cmd[1] = auipc(5'd10, 21'd0); // auipc a0, 0
abstract_cmd[2] = srli(5'd10, 5'd10, 6'd12); // srli a0, a0, 12
abstract_cmd[3] = slli(5'd10, 5'd10, 6'd12); // slli a0, a0, 12
abstract_cmd[4] = nop;
abstract_cmd[5] = nop;
abstract_cmd[6] = nop;
abstract_cmd[7] = nop;
abstract_cmd[8] = csrr(`CSR_DSCRATCH1, 5'd10); // csrr dscratch1, a0 恢复a0寄存器的值
abstract_cmd[9] = ebreak;
case (cmd_type)
CmdAccessRegister: begin
// unsupported reg size
if (cmd_aarsize > 3'h2 || cmd_aarpostincrement || cmd_regno >= 16'h1020) begin
abstract_cmd[0] = ebreak;
unsupported_command = 1'b1;
end else begin
// store a0 in dscratch1
abstract_cmd[0] = csrw(`CSR_DSCRATCH1, 5'd10); // csrw dscratch1, a0 保存a0寄存器的值
// write regs
if (cmd_transfer && cmd_write) begin
// a0
if (cmd_regno[12] && (cmd_regno[4:0] == 5'd10)) begin
// store s0 in dscratch
abstract_cmd[4] = csrw(`CSR_DSCRATCH0, 5'd8);
// load from data register
abstract_cmd[5] = load(cmd_aarsize, 5'd8, LoadBaseAddr, `DataBaseAddr);
// and store it in the corresponding CSR
abstract_cmd[6] = csrw(`CSR_DSCRATCH1, 5'd8);
// restore s0 again from dscratch
abstract_cmd[7] = csrr(`CSR_DSCRATCH0, 5'd8);
// GPR access
end else if (cmd_regno[12]) begin
abstract_cmd[4] = load(cmd_aarsize, cmd_regno[4:0], LoadBaseAddr, `DataBaseAddr);
// CSR access
end else begin
// data register to CSR
// store s0 in dscratch
abstract_cmd[4] = csrw(`CSR_DSCRATCH0, 5'd8);
// load from data register
abstract_cmd[5] = load(cmd_aarsize, 5'd8, LoadBaseAddr, `DataBaseAddr);
// and store it in the corresponding CSR
abstract_cmd[6] = csrw(cmd_regno[11:0], 5'd8);
// restore s0 again from dscratch
abstract_cmd[7] = csrr(`CSR_DSCRATCH0, 5'd8);
end
// read regs
end else if (cmd_transfer && (!cmd_write)) begin
// a0
if (cmd_regno[12] && (cmd_regno[4:0] == 5'd10)) begin
// store s0 in dscratch
abstract_cmd[4] = csrw(`CSR_DSCRATCH0, 5'd8);
// read value from CSR into s0
abstract_cmd[5] = csrr(`CSR_DSCRATCH1, 5'd8);
// and store s0 into data section
abstract_cmd[6] = store(cmd_aarsize, 5'd8, LoadBaseAddr, `DataBaseAddr);
// restore s0 again from dscratch
abstract_cmd[7] = csrr(`CSR_DSCRATCH0, 5'd8);
// GPR access
end else if (cmd_regno[12]) begin
abstract_cmd[4] = store(cmd_aarsize, cmd_regno[4:0], LoadBaseAddr, `DataBaseAddr);
// CSR access
end else begin
// CSR register to data
// store s0 in dscratch
abstract_cmd[4] = csrw(`CSR_DSCRATCH0, 5'd8);
// read value from CSR into s0
abstract_cmd[5] = csrr(cmd_regno[11:0], 5'd8);
// and store s0 into data section
abstract_cmd[6] = store(cmd_aarsize, 5'd8, LoadBaseAddr, `DataBaseAddr);
// restore s0 again from dscratch
abstract_cmd[7] = csrr(`CSR_DSCRATCH0, 5'd8);
end
end
end
if (cmd_postexec && (!unsupported_command)) begin
// issue a nop, we will automatically run into the program buffer
abstract_cmd[9] = nop;
end
end
// not supported at the moment:
// CmdQuickAccess:;
// CmdAccessMemory:;
default: begin
unsupported_command = 1'b1;
abstract_cmd[0] = ebreak;
end
endcase
end end
wire[63:0] rom_addr; wire[63:0] rom_addr;

View File

@ -15,9 +15,7 @@
*/ */
module jtag_sba #( module jtag_sba(
)(
input wire clk, input wire clk,
input wire rst_n, input wire rst_n,

View File

@ -20,8 +20,8 @@ module jtag_tap #(
parameter DMI_DATA_BITS = 32, parameter DMI_DATA_BITS = 32,
parameter DMI_OP_BITS = 2, parameter DMI_OP_BITS = 2,
parameter IR_BITS = 5, parameter IR_BITS = 5,
localparam TAP_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS, parameter TAP_REQ_BITS = DMI_ADDR_BITS + DMI_DATA_BITS + DMI_OP_BITS,
localparam DTM_RESP_BITS = TAP_REQ_BITS parameter DTM_RESP_BITS = TAP_REQ_BITS
)( )(
input wire jtag_tck_i, // JTAG test clock pad input wire jtag_tck_i, // JTAG test clock pad

View File

@ -15,15 +15,14 @@
*/ */
module jtag_top #( module jtag_top(
)(
input wire clk_i, input wire clk_i,
input wire rst_ni, input wire rst_ni,
output wire debug_req_o, output wire debug_req_o,
output wire ndmreset_o, output wire ndmreset_o,
output wire halted_o,
input wire jtag_tck_i, // JTAG test clock pad input wire jtag_tck_i, // JTAG test clock pad
input wire jtag_tdi_i, // JTAG test data input pad input wire jtag_tdi_i, // JTAG test data input pad
@ -74,6 +73,7 @@ module jtag_top #(
.dmi_ready_i (dmi_to_dm_ready), .dmi_ready_i (dmi_to_dm_ready),
.debug_req_o (debug_req_o), .debug_req_o (debug_req_o),
.ndmreset_o (ndmreset_o), .ndmreset_o (ndmreset_o),
.halted_o (halted_o),
.master_req_o (master_req_o), .master_req_o (master_req_o),
.master_gnt_i (master_gnt_i), .master_gnt_i (master_gnt_i),
.master_rvalid_i(master_rvalid_i), .master_rvalid_i(master_rvalid_i),

View File

@ -79,8 +79,8 @@ module obi_interconnect #(
// slave信号赋值 // slave信号赋值
generate generate
for (s = 0; s < SLAVES; s = s + 1) begin: slave_signal for (s = 0; s < SLAVES; s = s + 1) begin: slave_signal
assign slave_req_o[s] = master_req_i[master_sel_int[s]]; assign slave_req_o[s] = master_req_i[master_sel_int[s]] & granted_master[s];
assign slave_we_o[s] = master_we_i[master_sel_int[s]]; assign slave_we_o[s] = master_we_i[master_sel_int[s]] & granted_master[s];
assign slave_be_o[s] = master_be_i[master_sel_int[s]]; assign slave_be_o[s] = master_be_i[master_sel_int[s]];
assign slave_addr_o[s] = master_addr_i[master_sel_int[s]]; assign slave_addr_o[s] = master_addr_i[master_sel_int[s]];
assign slave_wdata_o[s] = master_wdata_i[master_sel_int[s]]; assign slave_wdata_o[s] = master_wdata_i[master_sel_int[s]];

View File

@ -37,8 +37,6 @@ module tinyriscv_soc_top(
); );
localparam int MASTERS = 3; // Number of master ports localparam int MASTERS = 3; // Number of master ports
localparam int SLAVES = 3; // Number of slave ports localparam int SLAVES = 3; // Number of slave ports
@ -86,54 +84,55 @@ module tinyriscv_soc_top(
wire ndmreset; wire ndmreset;
wire ndmreset_n; wire ndmreset_n;
wire debug_req; wire debug_req;
wire core_halted;
assign halted_ind_pin = core_halted;
tinyriscv_core #( tinyriscv_core #(
.DEBUG_HALT_ADDR(`DEBUG_ADDR_BASE + `HaltAddress), .DEBUG_HALT_ADDR(`DEBUG_ADDR_BASE + `HaltAddress),
.DEBUG_EXCEPTION_ADDR(`DEBUG_ADDR_BASE + `ExceptionAddress) .DEBUG_EXCEPTION_ADDR(`DEBUG_ADDR_BASE + `ExceptionAddress)
) u_tinyriscv_core ( ) u_tinyriscv_core (
.clk(clk), .clk (clk),
.rst_n(ndmreset_n), .rst_n (ndmreset_n),
.instr_req_o(master_req[CoreI]), .instr_req_o (master_req[CoreI]),
.instr_gnt_i(master_gnt[CoreI]), .instr_gnt_i (master_gnt[CoreI]),
.instr_rvalid_i(master_rvalid[CoreI]), .instr_rvalid_i (master_rvalid[CoreI]),
.instr_addr_o(master_addr[CoreI]), .instr_addr_o (master_addr[CoreI]),
.instr_rdata_i(master_rdata[CoreI]), .instr_rdata_i (master_rdata[CoreI]),
.instr_err_i(1'b0), .instr_err_i (1'b0),
.data_req_o(master_req[CoreD]), .data_req_o (master_req[CoreD]),
.data_gnt_i(master_gnt[CoreD]), .data_gnt_i (master_gnt[CoreD]),
.data_rvalid_i(master_rvalid[CoreD]), .data_rvalid_i (master_rvalid[CoreD]),
.data_we_o(master_we[CoreD]), .data_we_o (master_we[CoreD]),
.data_be_o(master_be[CoreD]), .data_be_o (master_be[CoreD]),
.data_addr_o(master_addr[CoreD]), .data_addr_o (master_addr[CoreD]),
.data_wdata_o(master_wdata[CoreD]), .data_wdata_o (master_wdata[CoreD]),
.data_rdata_i(master_rdata[CoreD]), .data_rdata_i (master_rdata[CoreD]),
.data_err_i(1'b0), .data_err_i (1'b0),
.irq_software_i(1'b0), .irq_software_i (1'b0),
.irq_timer_i(1'b0), .irq_timer_i (1'b0),
.irq_external_i(1'b0), .irq_external_i (1'b0),
.irq_fast_i(15'b0), .irq_fast_i (15'b0),
.debug_req_i(debug_req) .debug_req_i (debug_req)
); );
assign slave_addr_mask[Rom] = `ROM_ADDR_MASK; assign slave_addr_mask[Rom] = `ROM_ADDR_MASK;
assign slave_addr_base[Rom] = `ROM_ADDR_BASE; assign slave_addr_base[Rom] = `ROM_ADDR_BASE;
// 指令存储器 // 指令存储器
rom #( rom #(
.DP(`ROM_DEPTH) .DP(`ROM_DEPTH)
) u_rom( ) u_rom (
.clk(clk), .clk (clk),
.rst_n(ndmreset_n), .rst_n (ndmreset_n),
.addr_i(slave_addr[Rom]), .addr_i (slave_addr[Rom]),
.data_i(slave_wdata[Rom]), .data_i (slave_wdata[Rom]),
.sel_i(slave_be[Rom]), .sel_i (slave_be[Rom]),
.we_i(slave_we[Rom]), .we_i (slave_we[Rom]),
.data_o(slave_rdata[Rom]) .data_o (slave_rdata[Rom])
); );
assign slave_addr_mask[Ram] = `RAM_ADDR_MASK; assign slave_addr_mask[Ram] = `RAM_ADDR_MASK;
@ -141,49 +140,48 @@ module tinyriscv_soc_top(
// 数据存储器 // 数据存储器
ram #( ram #(
.DP(`RAM_DEPTH) .DP(`RAM_DEPTH)
) u_ram( ) u_ram (
.clk(clk), .clk (clk),
.rst_n(ndmreset_n), .rst_n (ndmreset_n),
.addr_i(slave_addr[Ram]), .addr_i (slave_addr[Ram]),
.data_i(slave_wdata[Ram]), .data_i (slave_wdata[Ram]),
.sel_i(slave_be[Ram]), .sel_i (slave_be[Ram]),
.we_i(slave_we[Ram]), .we_i (slave_we[Ram]),
.data_o(slave_rdata[Ram]) .data_o (slave_rdata[Ram])
); );
obi_interconnect #( obi_interconnect #(
.MASTERS(MASTERS), .MASTERS(MASTERS),
.SLAVES(SLAVES) .SLAVES(SLAVES)
) bus ( ) bus (
.clk_i(clk), .clk_i (clk),
.rst_ni(ndmreset_n), .rst_ni (ndmreset_n),
.master_req_i(master_req), .master_req_i (master_req),
.master_gnt_o(master_gnt), .master_gnt_o (master_gnt),
.master_rvalid_o(master_rvalid), .master_rvalid_o (master_rvalid),
.master_we_i(master_we), .master_we_i (master_we),
.master_be_i(master_be), .master_be_i (master_be),
.master_addr_i(master_addr), .master_addr_i (master_addr),
.master_wdata_i(master_wdata), .master_wdata_i (master_wdata),
.master_rdata_o(master_rdata), .master_rdata_o (master_rdata),
.slave_addr_mask_i(slave_addr_mask), .slave_addr_mask_i (slave_addr_mask),
.slave_addr_base_i(slave_addr_base), .slave_addr_base_i (slave_addr_base),
.slave_req_o(slave_req), .slave_req_o (slave_req),
.slave_gnt_i(slave_gnt), .slave_gnt_i (slave_gnt),
.slave_rvalid_i(slave_rvalid), .slave_rvalid_i (slave_rvalid),
.slave_we_o(slave_we), .slave_we_o (slave_we),
.slave_be_o(slave_be), .slave_be_o (slave_be),
.slave_addr_o(slave_addr), .slave_addr_o (slave_addr),
.slave_wdata_o(slave_wdata), .slave_wdata_o (slave_wdata),
.slave_rdata_i(slave_rdata) .slave_rdata_i (slave_rdata)
); );
rst_gen #( rst_gen #(
.RESET_FIFO_DEPTH(5) .RESET_FIFO_DEPTH(5)
) u_rst ( ) u_rst (
.clk(clk), .clk (clk),
.rst_ni(rst_ext_ni & (~ndmreset)), .rst_ni (rst_ext_ni & (~ndmreset)),
.rst_no(ndmreset_n) .rst_no (ndmreset_n)
); );
assign slave_addr_mask[JtagDevice] = `DEBUG_ADDR_MASK; assign slave_addr_mask[JtagDevice] = `DEBUG_ADDR_MASK;
@ -196,6 +194,7 @@ module tinyriscv_soc_top(
.rst_ni (rst_ext_ni), .rst_ni (rst_ext_ni),
.debug_req_o (debug_req), .debug_req_o (debug_req),
.ndmreset_o (ndmreset), .ndmreset_o (ndmreset),
.halted_o (core_halted),
.jtag_tck_i (sim_jtag_tck), .jtag_tck_i (sim_jtag_tck),
.jtag_tdi_i (sim_jtag_tdi), .jtag_tdi_i (sim_jtag_tdi),
.jtag_tms_i (sim_jtag_tms), .jtag_tms_i (sim_jtag_tms),

View File

@ -34,11 +34,14 @@ module tb_top_verilator #(
$display("No firmware specified"); $display("No firmware specified");
end end
end end
/*
reg result_printed;
always @(posedge clk_i or negedge rst_ni) begin always @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin if (!rst_ni) begin
result_printed <= 1'b0;
end else begin end else begin
if (!result_printed) begin
if (x26 == 32'b1) begin if (x26 == 32'b1) begin
if (x27 == 32'b1) begin if (x27 == 32'b1) begin
$display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~"); $display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~");
@ -61,11 +64,12 @@ module tb_top_verilator #(
$display("~~~~~~~~~~# # # # ######~~~~~~~~~~"); $display("~~~~~~~~~~# # # # ######~~~~~~~~~~");
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); $display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
end end
$finish; result_printed <= 1'b1;
end end
end end
end end
*/ end
tinyriscv_soc_top u_tinyriscv_soc_top( tinyriscv_soc_top u_tinyriscv_soc_top(
.clk(clk_i), .clk(clk_i),
.rst_ext_ni(rst_ni) .rst_ext_ni(rst_ni)