[libre-riscv-dev] HDL selection
Jacob Lifshay
programmerjake at gmail.com
Sun Nov 18 20:24:59 GMT 2018
On Sat, Nov 17, 2018, 06:08 Luke Kenneth Casson Leighton <lkcl at lkcl.net
wrote:
> RocketCore.scala: register file.
>
> https://github.com/freechipsproject/rocket-chip/blob/master/src/main/scala/rocket/RocketCore.scala
>
> (1) what on earth is canRead being set to false? that permanently
> stops read from working!
>
I think that's to enforce that read declarations have to come before write
declarations. Not sure why they are doing that.
> (2) what on earth is a "=/=" operator?
>
Inequality operator for generated code:
https://github.com/freechipsproject/chisel3/wiki/Builtin-Operators
> (3) what's an _2?
>
second element of a tuple
> (4) where are all the comments that are normally expected to be on
> source code files, explaining the parameters and the purpose of the
> class?
>
Missing; they probably figured it was obvious from the code: You'd use it
like:
val rf = new RegFile(31 /* register count */, 64 /* XLEN */, true /*
reading the zero reg returns zero */);
rf.write(rd, rf.read(rs1) + rf.read(rs2)); // generates a 2R1W register
file because read is called twice and write is called once where write
enable is rd =/= 0
> (5) what order are the parameters to "Mux"? what kind of "Mux" is it?
>
2-input mux: Mux(a, b, c) is the generated code version of C's a ? b : c
https://github.com/freechipsproject/chisel3/wiki/Builtin-Operators
>
> class RegFile(n: Int, w: Int, zero: Boolean = false) {
> private val rf = Mem(n, UInt(width = w))
> private def access(addr: UInt) = rf(~addr(log2Up(n)-1,0))
> private val reads = ArrayBuffer[(UInt,UInt)]()
> private var canRead = true
> def read(addr: UInt) = {
> require(canRead)
> reads += addr -> Wire(UInt())
> reads.last._2 := Mux(Bool(zero) && addr === UInt(0), UInt(0),
> access(addr))
> reads.last._2
> }
> def write(addr: UInt, data: UInt) = {
> canRead = false
> when (addr =/= UInt(0)) {
> access(addr) := data
> for ((raddr, rdata) <- reads)
> when (addr === raddr) { rdata := data }
> }
> }
> }
>
> -------
> Algol's RegisterFile class (myhdl).
> https://github.com/AngelTerrones/Algol/blob/master/Core/regfile.py
>
> (1) it's got standard python documentation strings.
> (2) Signal looks obvious what it does.
> (3) modbv doesn't.
> (4) _registers looks obvious. it's a list of 32 "signals".
> (5) read looks obvious (i left out the class "Port"), it goes "next
> read of port data is from the indexed register if the port's ra (read
> address) is non-zero.
> (6) write looks obvious (if the doc string isn't clear). update the
> target register (from wd) if the address (wa) isn't zero. oh and if
> the writePort isn't locked for some reason (we).
>
>
>
> def RegisterFile(clk,
> portA,
> portB,
> writePort):
> """
> The Register File (RF) module.
> 32 32-bit registers, with the register 0 hardwired to zero.
>
> :param clk: System clock
> :param portA: IO bundle (read port)
> :param portB: IO bundle (read port)
> :param writePort: IO bundle (write port)
> """
> _registers = [Signal(modbv(0)[32:]) for ii in range(0, 32)]
>
> @always_comb
> def read():
> """
> Asynchronous read operation.
> """
> portA.rd.next = _registers[portA.ra] if portA.ra != 0 else 0
> portB.rd.next = _registers[portB.ra] if portB.ra != 0 else 0
>
> @always(clk.posedge)
> def write():
> """
> Synchronous write operation.
>
> If the write address is zero, do nothing.
> """
> if writePort.wa != 0 and writePort.we == 1:
> _registers[writePort.wa].next = writePort.wd
>
> return read, write
>
>
> ------
> migen. can't find an example "register file", did find this, which is
> a fork of migen called "litex":
> https://www.bunniestudios.com/blog/?p=5018
>
> the key about litex (migen): *massive* incrreases in efficiency of the
> auto-generated Verilog source. far, far less resources utilised.
>
I don't litex is any better/worse than chisel for resource utilization,
it's just that they are both better than the IP that comes with Vivado,
which is particularly terrible. Note that I haven't tested anything
personally though.
Jacob
More information about the libre-riscv-dev
mailing list