RISC-V Notes

screenshot-2016-11-29-17-00-00

https://riscv.org/wp-content/uploads/2015/01/riscv-rocket-chip-generator-workshop-jan2015.pdf

src/main/scala/uncore/tilelink/Definitions.scala States the following for each steps:

  1. Acquire: used to initiate coherence protocol transactions in order to gain access to a cache blcok’s data with certain permissions enabled. … Acquires may contain data for Put or PutAtomic… After sending acquires, clients must wait for a manager to send them a Uncore Grant message in response
  2. Probe: used to force clients to release data or cede permissions on a cache block. Clients respond to probes with Release messages.
  3. Release: used to release data or permission back to the manager in response to Probe message. Can be used to volunatirly writeback data. (ex. event that dirty data must be evicted on cache miss).
  4. Grant: used to refill data or grant permissions requested of the manger agent via acquire message. Also used to ack the receipt of volunatry writeback from clients in the form of Release.
  5. Finish: used to provide global ordering of Txs. Sent as ack for receipt of grant message. When a Finish message is received, a manager knows it is safe to begin processing other transactions that touch the same cache block.

Cache Miss

On a miss, there is a block of code that adds the miss into the MSHR

// replacement policy
val replacer = p(Replacer)()
val s1_replaced_way_en = UIntToOH(replacer.way)
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)

// miss handling
mshrs.io.req.valid := s2_valid_masked && !s2_hit && (isPrefetch(s2_req.cmd) || isRead(s2_req.cmd) || isWrite(s2_req.cmd))
mshrs.io.req.bits := s2_req
mshrs.io.req.bits.tag_match := s2_tag_match
mshrs.io.req.bits.old_meta := Mux(s2_tag_match, L1Metadata(s2_repl_meta.tag, s2_hit_state), s2_repl_meta)
mshrs.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
mshrs.io.req.bits.data := s2_req.data
when (mshrs.io.req.fire()) { replacer.miss }
io.mem.acquire <> mshrs.io.mem_req

The miss should be processed by the MSHR by issuing an Acquire to the TileLink, and waiting for a Grant that’ll be filled into the mshrs.io.req.bits.way_en way.

In the MSHRFile class, there is a line of code as follows:

val sdq_enq = io.req.valid && io.req.ready && cacheable && isWrite(io.req.bits.cmd)

Thus I’m assuming the sdq stands for a Store Data Queue. Also, as we’re trying to prefetch misses (I think we can ignore this part for now…)

MSHR Issues Acquire Requests

 io.mem_req.valid := state === s_refill_req && fq.io.enq.ready
 io.mem_req.bits := req.old_meta.coh.makeAcquire(
 addr_block = Cat(io.tag, req_idx),
 client_xact_id = Bits(id),
 op_code = req.cmd)

This is a code snippet from the MSHR class.  The individual mshr.io.mem_req are connected via an arbiter in the MSHRFile class mem_req_arb.io. The mem_req_arb‘s out is connected to the io.mem_req which is then connected to the io.mem.acquire in the HellaCache class.

The snippet above sends out a Acquire requests if the state of the current MSHR is a refill request, and is ready to be enqueued into the Finish Queue. The address block is generated from the tag and index, and the op_code carries the command of the request. Also, an id is generated to create an client Transaction ID. However, the id the index of the MSHR in the MSHRFile.

State change: s_refill_req->s_refill_resp

The MSHR state change from the s_refill_req to s_refill_resp happens on an Acquire fire(). The fire() occurs when both the  object’s valid and ready bits are on at the same time.

object ReadyValidIO {
...
def fire(): Bool = target.ready && target.valid
}

Thus the acquire has been fed valid data, and the acquire has been switched to ready. The acquire has been successfully fired, and we’re waiting for a grant response from the uncore.

Check the code from line:304

Xilinx SDK Hello World Build Errors

Cannot find libz.so.1

Got an error in the Xilinx SDK where the error message was that the arm gcc compiler was missing libz.so.1

Not sure if this will help but I tried installing the 32-bit libz library

apt-get install zlib1g:i386

Cannot find -lxil

Seems like somebody else had a problem here

And the third message had the answer:

I wasn’t able to solve it. It was a simple project, so I just remade it and it worked.

So I cleaned the build and remade it.

Driving FPGA IPs from Linux

 few links that’ll help me get started:

Zedboard.org forum

http://fpgacpu.wordpress.com/2013/05/24/yet-another-guide-to-running-linaro-ubuntu-desktop-on-xilinx-zynq-on-the-zedboard/

http://fpgacpu.wordpress.com/2013/05/28/how-to-design-and-access-a-memory-mapped-device-part-one/

http://fpgacpu.wordpress.com/2013/05/28/how-to-design-and-access-a-memory-mapped-device-part-two/

Forum Posts:

http://zedboard.com/content/how-communicate-fpga-linux

http://zedboard.org/content/interrupt-handler-kernel-module

By Sven Andersson

http://svenand.blogdrive.com/archive/203.html

Xilinx Wiki code

http://www.wiki.xilinx.com/Linux+User+Mode+Pseudo+Driver

Generating DTS and DTIs from Xilinx SDK

Xilinx Tutorial

DTB compiling help

When building the kernel with the uImage we need a mkimage which is in the uboot. Also uboot requires dtc which is available on the Fetch sources.

At the moment the kernel doesn’t boot after Starting kernel ...

Building the Kernel

The Xilinx manual makes the kernel load at 0x208000 however the u-boot boots from 0x8000; thus changed the

make ARCH=arm xilinx_zynq_defconfig
make ARCH=arm menuconfig
make ARCH=arm uImage LOADADDR=0x00008000

Also, changed the linux-xlnx branch from master to the xilinx-v2016.2 tag.

More problems: Nice forum post

https://forums.xilinx.com/t5/Embedded-Linux/Zynq-Linux-Freeze-on-Memory-Mapped-Peripheral-Write/td-p/246156

This post was helpful. It first identified that a problem may be in the FSBL

From the u-boot if the following command does not work, then we may need to recompile the FSBL

md.l 0x43c00000

If this does not work, the translation table in the FSBL must be incorrect. (This may be because we use the UCR-Bar’s files.Build the FSBL with the boot.bif in the UCR-Bar repo.

This page tells us how to create the FSBL Boot image, and This page how to build the FSBL from our IP configuration.

Done! – The process

 

Vivado HLS (2016.02) co-simulation build error on Ubuntu 14.04 (crti.o not found)

Vivado HLS 2016.02 has an error when building binary files (for co-simulation) on Ubuntu 14.04. (Don’t know about other distributions, or other versions of Ubuntu)

I got my help from this blog post.

The problem I got was as follows:

INFO: [HLS 200-10] In directory '/home/username/Vivado_HLS_projects/XorGenerator/XorGenerator/sim/wrapc'
clang: warning: argument unused during compilation: '-fno-builtin-isinf'
clang: warning: argument unused during compilation: '-fno-builtin-isnan'
INFO: [APCC 202-3] Tmp directory is /tmp/apcc_db_username/160961476017075859177
INFO: [APCC 202-1] APCC is done.
Generating cosim.tv.exe
In file included from apatb_do_xor.cpp:18:0:
/opt/Xilinx/Vivado_HLS/2016.2/include/ap_stream.h:70:2: warning: #warning AP_STREAM macros are deprecated. Please use hls::stream<> from "hls_stream.h" instead. [-Wcpp]
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory

So the problem was that crt1.o and crti.o are note found. Just to give you a hint, these files are under /usr/lib/x86_64-linux_gnu

However instead of adding that directory as the build path or Library path (which I think is the intuition and the right way to do it…) The workaround in the blog post is to copy the crti.o, crt1.o, and crtn.o file to the Vivado HLS's gcc directories.

The path has changed since Vivado HLS 2012.02 as in the post.

Now the path is at /opt/Xilinx/Vivado_HLS/2016.2/lnx64/tools/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.6.3/

Thus you will want to execute the following command:

cp /usr/lib/x86_64-linux-gnu/crt?.o /opt/Xilinx/Vivado_HLS/2016.2/lnx64/tools/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.6.3/

Cheers 🙂

Scala Language

In our FPGA project we’ll be using the UC Berkeley Architecture Research team’s Rocket core. (Most likely we’ll be using it) The core is written in the Scala language and is compiled via Chisel into C++ simulator or Verilog for FPGA/ASIC.

Now I need to know Scala to fully understand the rocket core, and so I’m looking throught the Scala Tutorial, offered at the Scala Language site.

Interesting Features

Method call

Methods taking one argument can be used with an infix syntax.

df format now
df.format(now)

These have the same meaning syntactically. Seems alot like the style of smalltalk (and Objective-C)

Function are Objects (Passing functions as arguments)


object Timer {
  def oncePerSecond(callback: () => Unit) {
    while (true) { callback(); Thread sleep 1000 }
  }
  def timeFlies() {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies)
  }
}

Anonymous Functions

object TimerAnonymous {
  def oncePerSecond(callback: () => Unit) {
    while (true) { callback(); Thread sleep 1000 }
  }
  def main(args: Array[String]) {
    oncePerSecond(() =>
      println("time flies like an arrow..."))
  }
}

Notice that the () =&gt; denotes an anonymous function. I think it would be a lambda function 😉

Vivado License Ubuntu 14.04 Zeroed NIC Interface problem

During the Activation (License management) of Vivado HLx 2016.2 I encounterd a problem where I could copy the license (received via email), however when viewing license information, I couldn’t find my license.

I checked the host information and found that the Network Interface Card ID was zeroed.
Screen Shot 2016-10-03 at 3.40.45 PM.png

I think a possible reason is because from some point in Ubuntu, they followed Redhat’s convention for the nic names. The NIC names used to be ethX, but now they are emX because the NICs I use are embedded onto the mainboard.

I found that the module that changes the name is biosdevname and can be disabled by setting biosdevname=0 in the linux bootup parameters.

A Stackoverflow Q&A discusses this problem, and we can either:

I decided to try the grub option.

If you use static IP setting, and use /etc/network/interfaces, don’t forget to update your settings before resetting. (You won’t be able to log on, or the system will delay the boot for 60 seconds to try to get connectivity)

This issue is also reported on the Xilinx Forums, however I’m not sure if there is a fix going on.