Skip to content

Modify GCD.scala to Adder.scala in Chipyard

aneesullah edited this page Nov 5, 2022 · 1 revision

The goal of this wiki doc is to guide you to modify the GCD.scala example found in generators/chipyard/src/main/scala/example. The GCD.scala example is a very nice example as it can create a perhiperal both for TileLink and AXI4 interconnects. Another aspect is that it also includes the blackbox for verilog modules, so if you have a verilog module that you want to connect to rocketchip this is a nice place to start with. The Adder MMIO Peripheral that you will create takes two inputs x and y (exposed as memory-mapped registers) and produces an output adder (another memory-mapped register). You can follow these steps:

1- Create a new file Adder.scala in example folder.
2- Copy the code from GCD.scala into the new file.
3- Replace GCD everywhere with Adder, for example, GCDParams with AdderParams, GCDKey with AdderKey, GCDIO with AdderIO and so on. An easy approach would be to replace "GCD" with "Adder" in the code. Note "GCD" shall be considered case sensitive and "gcd" shall be replaced with "adder" to make differentiation easier.
4- Now we need to make logic changes, first is change the class AdderIO to the following
class AdderIO(val w: Int) extends Bundle {
val x = Input(UInt(w.W))
val y = Input(UInt(w.W))
val adder = Output(UInt(w.W))
}
5- Next is modify the AdderMMIOChiselModule as following:
// DOC include start: Adder chisel
class AdderMMIOChiselModule(val w: Int) extends Module
with HasAdderIO
{
val adder = RegInit(0.U(w.W))
io.adder := adder
adder := io.x + io.y
}
// DOC include end: Adder chisel
6- Next is to modify the AdderModule as following:
// DOC include start: Adder instance regmap
trait AdderModule extends HasRegMap {
val io: AdderTopIO
implicit val p: Parameters
def params: AdderParams
val x = Reg(UInt(params.width.W))
val y = Reg(UInt(params.width.W))
val adder = Reg(UInt(params.width.W))
val impl = if (params.useBlackBox) {
Module(new AdderMMIOBlackBox(params.width))
} else {
Module(new AdderMMIOChiselModule(params.width))
}
impl.io.x := x
impl.io.y := y
adder := impl.io.adder
regmap(
0x00 -> Seq(
RegField.w(params.width, x)),
0x04 -> Seq(
RegField.w(params.width, y)),
0x08 -> Seq(
RegField.r(params.width, adder)))
}
// DOC include end: Adder instance regmap
7- Changes in Chisel are complete, you can go now to tests/gcd.c file, create a new c file called Adder.c, copy the code from gcd.c here and modify. Note: Since, there are three registers exposed from Adder MMIO peripheral, we need to change the #define for x, y, and adder (which is the output from Adder MMIO perhipheral), Similarly, you need to change the adder_ref, complete code is the following:

#include<stdio.h>
#include "mmio.h"
#define ADDER_X 0x2000
#define ADDER_Y 0x2004
#define ADDER_ADDER 0x2008
unsigned int adder_ref(unsigned int x, unsigned int y) {
return (x + y);
}
// DOC include start: ADDER test
int main(void)
{
printf("Enter ADDER computation:\n\r");
uint32_t result, ref, x = 20, y = 15;
reg_write32(ADDER_X, x);
reg_write32(ADDER_Y, y);
result = reg_read32(ADDER_ADDER);
ref = adder_ref(x, y);
if (result != ref) {
printf("Hardware result %d does not match reference value %d\n", result, ref);
return 1;
}
printf("ADDITION of 20 and 15 is %d\n\r",result);
return 0;
}
// DOC include end: ADDER test

Clone this wiki locally