Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Nov 14, 2023
2 parents e71b1be + 940fb50 commit 6734c7b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 20 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,12 @@ Also there is a few environnement variable that you can use to modulate the rand
| VEXRISCV_REGRESSION_CONFIG_DEMW_RATE | 0.0-1.0 | Chance to generate a config with writeback stage |
| VEXRISCV_REGRESSION_CONFIG_DEM_RATE | 0.0-1.0 | Chance to generate a config with memory stage |

## Basic Verilator simulation

To run basic simulation with stdout and no tracing, loading a binary directly is supported with the `RUN_HEX` variable of `src/test/cpp/regression/makefile`. This has a significant performance advantage over using GDB over OpenOCD with JTAG over TCP. VCD tracing is supported with the makefile variable `TRACE`.

## Interactive debug of the simulated CPU via GDB OpenOCD and Verilator

To use this, you just need to use the same command as with running tests, but adding `DEBUG_PLUGIN_EXTERNAL=yes` in the make arguments.
This works for the `GenFull` configuration, but not for `GenSmallest`, as this configuration has no debug module.

Expand Down
4 changes: 2 additions & 2 deletions doc/nativeJtag/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ as given could move with future changes to the file:
```
[254] val jtagCtrl = JtagTapInstructionCtrl()
[255] val tap = jtagCtrl.fromXilinxBscane2(userId = 2)
[256] jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK))
[256] jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK),0)
```
Changing the above lines, removes the Murax SoC’s JTAG ports as pins of the FPGA and inserts the BSCANE2 Xilinx
Debug IP to which the JTAG signals are now connected.
Expand Down Expand Up @@ -84,7 +84,7 @@ in e.g. the path: `project_name.srcs\sources_1\imports\Downloads`
[44] wire tesic_tdo;
[45] reg soc_tck,soc_tms,soc_tdi;
[46] wire soc_tdo;
[47]
[47]
[48] always @(*) begin
[49] {soc_tck, soc_tms, soc_tdi } = {tck,tms,tdi};
[50] tdo = soc_tdo;
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ object VexRiscvAhbLite3{
// // On Artix FPGA jtag :
// val jtagCtrl = JtagTapInstructionCtrl()
// val tap = jtagCtrl.fromXilinxBscane2(userId = 1)
// jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK))
// jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK),0)
}
case _ =>
}
Expand Down
21 changes: 11 additions & 10 deletions src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -225,29 +225,30 @@ case class DBusSimpleBus(bigEndian : Boolean = false) extends Bundle with IMaste
bus
}

def toAhbLite3Master(avoidWriteToReadHazard : Boolean): AhbLite3Master = {
def toAhbLite3Master(avoidWriteToReadHazard : Boolean, withHalfRate : Boolean = true): AhbLite3Master = {
val bus = AhbLite3Master(DBusSimpleBus.getAhbLite3Config())
bus.HADDR := this.cmd.address
bus.HWRITE := this.cmd.wr
bus.HSIZE := B(this.cmd.size, 3 bits)
val cmdBuffer = this.cmd.pipelined(halfRate = withHalfRate)
bus.HADDR := cmdBuffer.address
bus.HWRITE := cmdBuffer.wr
bus.HSIZE := B(cmdBuffer.size, 3 bits)
bus.HBURST := 0
bus.HPROT := "1111"
bus.HTRANS := this.cmd.valid ## B"0"
bus.HTRANS := cmdBuffer.valid ## B"0"
bus.HMASTLOCK := False
bus.HWDATA := RegNextWhen(this.cmd.data, bus.HREADY)
this.cmd.ready := bus.HREADY
bus.HWDATA := RegNextWhen(cmdBuffer.data, bus.HREADY)
cmdBuffer.ready := bus.HREADY

val pending = RegInit(False) clearWhen(bus.HREADY) setWhen(this.cmd.fire && !this.cmd.wr)
val pending = RegInit(False) clearWhen(bus.HREADY) setWhen(cmdBuffer.fire && !cmdBuffer.wr)
this.rsp.ready := bus.HREADY && pending
this.rsp.data := bus.HRDATA
this.rsp.error := bus.HRESP

if(avoidWriteToReadHazard) {
val writeDataPhase = RegNextWhen(bus.HTRANS === 2 && bus.HWRITE, bus.HREADY) init (False)
val potentialHazard = this.cmd.valid && !this.cmd.wr && writeDataPhase
val potentialHazard = cmdBuffer.valid && !cmdBuffer.wr && writeDataPhase
when(potentialHazard) {
bus.HTRANS := 0
this.cmd.ready := False
cmdBuffer.ready := False
}
}
bus
Expand Down
35 changes: 30 additions & 5 deletions src/main/scala/vexriscv/plugin/PmpPluginOld.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,29 @@ case class PmpRegister(previous : PmpRegister) extends Area {
// Computed PMP region bounds
val region = new Area {
val valid, locked = Bool
val start, end = UInt(32 bits)

// The calculated start & end addresses can overflow xlen by 4 bit:
//
// - 2 bit, as the pmpaddrX registers are defined as to encode
// [XLEN + 2 downto 2] addresses.
//
// - 2 bit, as for NAPOT the most significant 0 bit encodes the region
// length, with this bit included in the range!
//
// This means that (for xlen == 32 bit)
//
// pmpcfg(X / 4)(X % 4) = NAPOT
// pmpaddrX = 0xFFFFFFFF
//
// will expand to
//
// start (inclusive): 0x000000000 << 2
// end (exclusive): 0x200000000 << 2
//
// hence requiring xlen + 2 + 2 bit to represent the exclusive end
// address. This could be optimized by using a saturating add, or making the
// end address exclusive.
val start, end = UInt(36 bits)
}

when(~state.l) {
Expand All @@ -114,9 +136,12 @@ case class PmpRegister(previous : PmpRegister) extends Area {
}
}

val shifted = state.addr |<< 2
val mask = state.addr & ~(state.addr + 1)
val masked = (state.addr & ~mask) |<< 2
// Extend state.addr to 36 bits, to avoid these computations overflowing (as
// explained above):
val extended_addr = (B"00" ## state.addr.asBits).asUInt
val shifted = extended_addr << 2
val mask = extended_addr ^ (extended_addr + 1)
val masked = (extended_addr & ~mask) << 2

// PMP changes take effect two clock cycles after the initial CSR write (i.e.,
// settings propagate from csr -> state -> region).
Expand All @@ -135,7 +160,7 @@ case class PmpRegister(previous : PmpRegister) extends Area {
}
is(NAPOT) {
region.start := masked
region.end := masked + ((mask + 1) |<< 3)
region.end := masked + ((mask + 1) << 2)
}
default {
region.start := 0
Expand Down
4 changes: 2 additions & 2 deletions src/test/cpp/common/jtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class Jtag : public TimeProcess{
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

//---- Bind the address struct to the socket ----//
bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
::bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

//---- Listen on the socket, with 5 max connection requests queued ----//
listen(serverSocket,1);
Expand Down Expand Up @@ -174,4 +174,4 @@ class Jtag : public TimeProcess{
schedule(tooglePeriod);
}

};
};

0 comments on commit 6734c7b

Please sign in to comment.