1
0
rocket-chip/vsrc/AsyncMailbox.v
Megan Wachs 3dd51ff734 This commit adds Logic & test support for JTAG implementation of Debug Transport Module.
- The DebugTransportModuleJtag is written in Verilog. It probably could be written in
  Chisel except for some negative edge clocking requirement.
- For real implementations, the AsyncDebugBusTo/From is insufficient. This commit
  includes cases where they are used, but because they are not reset asynchronously,
  a Verilog 'AsyncMailbox' is used when p(AsyncDebug) is false.
- This commit differs significantly from the earlier attempt. Now, the
  DTM and synchronizer is instantiated within Top, as it is a real piece of
  hardware (vs. test infrastructure).
-TestHarness takes a parameter vs. creating an entirely new TestHarness class.
It does not make sense to instantiate TestHarness when p(IncludeJtagDTM) is false,
and it would not make sense to insantiate some other TestHarness if p(IncludeJtagDTM)
is true.

To build Verilog which includes the JtagDTM within Top:

make CONFIG=WithJtagDTM_...

To test using gdb->OpenOCD->jtag_vpi->Verilog:

First, install openocd (included in this commit)

./bootstrap
./configure --prefix=$OPENOCD --enable-jtag-vpi
make
make install

Then to run a simulation:

On a 32-bit core:

$(ROCKETCHIP)/riscv-tools/riscv-tests/debug/gdbserver.py \
  --run ./simv-TestHarness-WithJtagDTM_... \
  --cmd="$OPENOCD/bin/openocd --s $OPENOCD/share/openocd/scripts/" \
  --freedom-e300-sim \
  SimpleRegisterTest.test_s0

On a 64-bit core:

$(ROCKETCHIP)/riscv-tools/riscv-tests/debug/gdbserver.py \
  --run ./simv-TestHarness-WithJtagDTM_... \
  --cmd="$OPENOCD/bin/openocd --s $OPENOCD/share/openocd/scripts/" \
  --freedom-u500-sim \
  SimpleRegisterTest.test_s0
2016-08-19 16:08:31 -07:00

155 lines
3.7 KiB
Verilog

module AsyncMailbox (
// Write Interface
enq_clock
, enq_reset
, enq_ready
, enq_valid
, enq_bits
// Read Interface
, deq_clock
, deq_reset
, deq_ready
, deq_valid
, deq_bits
);
//--------------------------------------------------------
// Parameter Declarations
parameter WIDTH = 64;
//--------------------------------------------------------
// I/O Declarations
// Write Interface
input enq_clock;
wire w_clock = enq_clock;
input enq_reset;
wire w_reset = enq_reset;
output enq_ready;
wire w_ready;
assign enq_ready = w_ready;
input enq_valid;
wire w_valid = enq_valid;
input [WIDTH - 1 : 0 ] enq_bits;
wire [WIDTH - 1 : 0 ] w_bits = enq_bits;
// Read Interface
input deq_clock;
wire r_clock = deq_clock;
input deq_reset;
wire r_reset = deq_reset;
output deq_valid;
wire r_valid;
assign deq_valid = r_valid;
input deq_ready;
wire r_ready = deq_ready;
output [WIDTH - 1 : 0] deq_bits;
wire [WIDTH - 1 : 0] r_bits;
assign deq_bits = r_bits;
//--------------------------------------------------------
// FIFO Memory Declaration
reg [WIDTH - 1 :0] mailboxReg;
//--------------------------------------------------------
// Reg and Wire Declarations
wire w_full;
wire w_fire;
wire r_empty;
wire r_fire;
// Read & Write Address Pointers
reg w_wrAddrReg;
wire w_wrAddrNxt;
reg r_rdAddrReg;
wire r_rdAddrNxt;
reg wrAddrReg_sync;
reg rdAddrReg_sync;
reg r_wrAddrReg;
reg w_rdAddrReg;
//--------------------------------------------------------
// Reg and Wire Declarations
assign w_full = ~(w_wrAddrReg == r_rdAddrReg);
assign w_wrAddrNxt = ~w_wrAddrReg ;
assign r_rdAddrNxt = ~r_rdAddrReg;
assign r_empty = (r_wrAddrReg == r_rdAddrReg);
assign w_ready = ~w_full;
assign w_fire = w_ready & w_valid;
// Read Logic
assign r_valid = ~r_empty;
assign r_fire = r_ready & r_valid;
assign r_bits = mailboxReg;
always @(posedge w_clock) begin
if (w_fire) begin
mailboxReg <= w_bits;
end
end
//--------------------------------------------------------
// Sequential logic
//
always @(posedge w_clock or posedge w_reset) begin
if (w_reset ) begin
w_wrAddrReg <= 1'b0;
rdAddrReg_sync <= 1'b0;
w_rdAddrReg <= 1'b0;
end else begin
if (w_fire) begin
w_wrAddrReg <= w_wrAddrNxt;
end
rdAddrReg_sync <= r_rdAddrReg;
w_rdAddrReg <= rdAddrReg_sync;
end
end
always @(posedge r_clock or posedge r_reset) begin
if (r_reset) begin
r_rdAddrReg <= 1'b0;
wrAddrReg_sync <= 1'b0;
r_wrAddrReg <= 1'b0;
end else begin
if (r_fire) begin
r_rdAddrReg <= r_rdAddrNxt;
end
wrAddrReg_sync <= w_wrAddrReg;
r_wrAddrReg <= wrAddrReg_sync;
end
end // always @ (posedge r_clock)
endmodule // AsyncMailbox