-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MultiCycle Top.scala, ALU.scala TopTests and launcher added
- Loading branch information
Showing
8 changed files
with
299 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env bash | ||
|
||
TESTER_BACKENDS=verilator sbt "test:run-main MultiCycle.Launcher $1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Please run ./run-multi.sh Top or ./run-multi.sh ALU | ||
# DO NOT run ./run-multi.sh, which will test Top and ALU both. | ||
|
||
# Add several blank lines | ||
echo -e "\n\n\n\n\n\n\n\n" | ||
|
||
sbt "test:run-main MultiCycle.Launcher $1" |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//************************************************************************** | ||
//-------------------------------------------------------------------------- | ||
// ercesiMIPS Multi Cycle Processor ALU for 9 instructions | ||
// | ||
// Meng Zhang | ||
// version 0.1 | ||
//-------------------------------------------------------------------------- | ||
//************************************************************************** | ||
|
||
package MultiCycle | ||
|
||
import chisel3._ | ||
|
||
|
||
// For our first sample ALU with 9 Insts | ||
// The supported instruction is following: | ||
// ADD 000000 sssss ttttt ddddd 00000 100000 //R type (signed) | ||
// SUB 000000 sssss ttttt ddddd 00000 100010 //R type (signed) | ||
// OR 000000 sssss ttttt ddddd 00000 100101 //R type (unsigned) | ||
// AND 000000 sssss ttttt ddddd 00000 100100 //R type (unsigned) | ||
// ORI 001101 sssss ttttt iiiii iiiii iiiiii //I type (unsigned) | ||
// ANDI 001100 sssss ttttt iiiii iiiii iiiiii //I type (unsigned) | ||
// LW 100011 sssss ttttt iiiii iiiii iiiiii //I type (signed imm) | ||
// SW 101011 sssss ttttt iiiii iiiii iiiiii //I type (signed imm) | ||
// BEQ 000100 sssss ttttt iiiii iiiii iiiiii //I type (signed imm) | ||
// SLT 000000 sssss ttttt ddddd 00000 101010 //R type (signed) | ||
// JUMP 000010 iiiii iiiii iiiii iiiii iiiiii //J type (signed imm) | ||
// Although 11 instruction implmented in this class, only | ||
// SUB, ADD, AND, OR, and SLT, BEQ in ALU operations | ||
//---------------------------------------------------// | ||
|
||
object ALU | ||
{ | ||
def FN_AND = 0.U(3.W) //0000 | ||
def FN_OR = 1.U(3.W) //0001 | ||
def FN_ADD = 2.U(3.W) //0010 | ||
def FN_SUB = 6.U(3.W) //0110 | ||
def FN_SLT = 7.U(3.W) //0111 | ||
|
||
def FN_BEQ = FN_SUB //0111 | ||
|
||
def isSub(cmd: UInt) = (cmd === FN_SUB) || (cmd === FN_SLT) | ||
} | ||
|
||
import ALU._ | ||
|
||
class ALU extends Module{ | ||
val io = IO(new Bundle{ | ||
val in1 = Input(UInt(32.W)) | ||
val in2 = Input(UInt(32.W)) | ||
val ALUctr = Input(UInt(3.W)) | ||
val ALUout = Output(UInt(32.W)) | ||
val cmp_out = Output(Bool()) | ||
}) | ||
|
||
//val SIntA = SInt(32.W) | ||
//val SIntB = SInt(32.W) | ||
|
||
// ADD, SUB | ||
val in2_inv = Mux(isSub(io.ALUctr), ~io.in2, io.in2) | ||
val in1_xor_in2 = io.in1 ^ io.in2 | ||
val adder_out = io.in1 + in2_inv + isSub(io.ALUctr) | ||
|
||
// SLT and BEQ comparation Output | ||
// For BEQ, cmp_out = (in1_xor_in2 === 0.U) | ||
// For SLT, cmp_out = adder_out(31) if io.in1(31) != io.in2(31) | ||
// Otherwise, cmp_out = adder_out(31) | ||
io.cmp_out := Mux(io.ALUctr === FN_BEQ, in1_xor_in2 === 0.U, | ||
Mux(io.in1(31) != io.in2(31), adder_out(31), | ||
Mux(adder_out(31), true.B, false.B))) | ||
|
||
// AND, OR, however this can also output XOR | ||
val logic_out = Mux(io.ALUctr === FN_OR, in1_xor_in2, 0.U) | | ||
Mux(io.ALUctr === FN_OR || io.ALUctr === FN_AND, io.in1 & io.in2, 0.U) | ||
|
||
val out = Mux(io.ALUctr === FN_ADD || io.ALUctr === FN_SUB, | ||
adder_out, logic_out) | ||
|
||
io.ALUout := out | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//************************************************************************** | ||
//-------------------------------------------------------------------------- | ||
// ercesiMIPS Multi Cycle Processor Top | ||
// | ||
// Meng zhang | ||
// version 0.1 | ||
//-------------------------------------------------------------------------- | ||
//************************************************************************** | ||
|
||
package MultiCycle | ||
|
||
import chisel3._ | ||
import chisel3.iotesters.Driver | ||
//import utils.ercesiMIPSRunner | ||
class TopIO extends Bundle() { | ||
val boot = Input(Bool()) | ||
// imem and dmem interface for Tests | ||
val test_im_wr = Input(Bool()) | ||
val test_im_rd = Input(Bool()) | ||
val test_im_addr = Input(UInt(32.W)) | ||
val test_im_in = Input(UInt(32.W)) | ||
val test_im_out = Output(UInt(32.W)) | ||
|
||
val test_dm_wr = Input(Bool()) | ||
val test_dm_rd = Input(Bool()) | ||
val test_dm_addr = Input(UInt(32.W)) | ||
val test_dm_in = Input(UInt(32.W)) | ||
val test_dm_out = Output(UInt(32.W)) | ||
|
||
val valid = Output(Bool()) | ||
} | ||
|
||
class Top extends Module() { | ||
val io = IO(new TopIO())//in chisel3, io must be wrapped in IO(...) | ||
val cpath = Module(new CtlPath()) | ||
val dpath = Module(new DatPath()) | ||
|
||
cpath.io.ctl <> dpath.io.ctl | ||
cpath.io.dat <> dpath.io.dat | ||
io.valid := cpath.io.valid | ||
cpath.io.boot := io.boot | ||
|
||
val imm = Mem(256, UInt(32.W)) | ||
val dmm = Mem(1024, UInt(32.W)) | ||
io.test_dm_out := 0.U | ||
io.test_im_out := 0.U | ||
cpath.io.Inst := 0.U | ||
when (io.boot && io.test_im_wr){ | ||
imm(io.test_im_addr >> 2) := io.test_im_in | ||
cpath.io.Inst := 0.U | ||
} | ||
when (io.boot && io.test_dm_wr){ | ||
dmm(io.test_dm_addr >> 2) := io.test_dm_in | ||
cpath.io.Inst := 0.U | ||
} | ||
when (io.boot && io.test_im_rd){ | ||
io.test_im_out := imm(io.test_im_addr >> 2) | ||
cpath.io.Inst := 0.U | ||
} | ||
when (io.boot && io.test_dm_rd){ | ||
io.test_dm_out := dmm(io.test_dm_addr >> 2) | ||
cpath.io.Inst := 0.U | ||
} | ||
when (!io.boot){ | ||
cpath.io.Inst := Mux(io.boot, 0.U, imm(dpath.io.imem_addr >> 2)) | ||
dpath.io.dmem_datOut := dmm(dpath.io.dmem_addr >> 2) | ||
when (cpath.io.MemWr) { | ||
dmm(dpath.io.dmem_addr >> 2) := dpath.io.dmem_datIn | ||
} | ||
} | ||
|
||
val clk_cnt = RegInit(0.U(32.W)) | ||
clk_cnt := clk_cnt + 1.U | ||
|
||
printf("Cyc=%d, pc=0x%x, Inst=0x%x, boot=%d, dmem_in = 0x%x, rd_dmm=0x%x, dmm=0x%x\n", | ||
clk_cnt, | ||
dpath.io.imem_addr, | ||
cpath.io.Inst, | ||
cpath.io.boot, | ||
dpath.io.dmem_datIn, | ||
io.test_dm_out, | ||
dmm(io.test_dm_addr >> 2)) | ||
//... | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// See LICENSE.txt for license details. | ||
//************************************************************************** | ||
//-------------------------------------------------------------------------- | ||
// ercesiMIPS Single Cycle Processor Test Launcher | ||
// | ||
// Meng zhang | ||
// version 0.1 | ||
//-------------------------------------------------------------------------- | ||
//************************************************************************** | ||
|
||
package MultiCycle | ||
|
||
import chisel3._ | ||
import chisel3.iotesters.Driver | ||
import utils.ercesiMIPSRunner | ||
|
||
object Launcher { | ||
val tests = Map( | ||
|
||
"ALU" -> { (backendName: String) => | ||
Driver(() => new ALU(), backendName) { | ||
(c) => new ALUTests(c) | ||
} | ||
}, | ||
"Top" -> { (backendName: String) => | ||
Driver(() => new Top(), backendName) { | ||
(c) => new TopTests(c) | ||
} | ||
} | ||
/*, | ||
"CtlPath" -> { (backendName: String) => | ||
Driver(() => new CtlPath(), backendName) { | ||
(c) => new CtlPathTests(c) | ||
} | ||
}*/ | ||
/*, | ||
"ALU11" -> { (backendName: String) => | ||
Driver(() => new ALU11(), backendName) { | ||
(c) => new ALU11Tests(c) | ||
} | ||
}, | ||
"Top" -> { (backendName: String) => | ||
Driver(() => new Top(), backendName) { | ||
(c) => new TopTests(c) | ||
} | ||
}*/ | ||
) | ||
|
||
def main(args: Array[String]): Unit = { | ||
ercesiMIPSRunner(tests, args) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//************************************************************************** | ||
//-------------------------------------------------------------------------- | ||
// ercesiMIPS Multi Cycle Processor ALU Test | ||
// | ||
// Meng zhang | ||
// version 0.1 | ||
//-------------------------------------------------------------------------- | ||
//************************************************************************** | ||
|
||
|
||
package MultiCycle | ||
|
||
import chisel3.iotesters.PeekPokeTester | ||
import java.io.PrintWriter | ||
import java.io.File | ||
import scala.io.Source | ||
|
||
class TopTests(c: Top) extends PeekPokeTester(c) { | ||
def asUInt(InInt: Int) = (BigInt(InInt >>> 1) << 1) + (InInt & 1) | ||
|
||
// Reset the CPU | ||
def TopBoot() = { | ||
poke(c.io.boot, 1) | ||
poke(c.io.test_im_wr, 0) | ||
poke(c.io.test_dm_wr, 0) | ||
step(1) | ||
} | ||
|
||
// Initialize the IMM content from file "inst.s", | ||
// which could be dumped from MARS. | ||
def WriteImm () = { | ||
val filename = "inst2.s" | ||
var addr = 0 | ||
var Inst = 0 | ||
for (line <- Source.fromFile(filename).getLines){ | ||
Inst = Integer.parseUnsignedInt(line, 16) | ||
poke(c.io.boot, 1) | ||
poke(c.io.test_im_wr, 1) | ||
poke(c.io.test_im_addr, addr*4) | ||
poke(c.io.test_im_in, asUInt(Inst)) | ||
addr = addr + 1 | ||
step(1) | ||
} | ||
} | ||
|
||
// Reset CPU | ||
TopBoot() | ||
|
||
// Init IMM | ||
WriteImm() | ||
|
||
// Run the CPU for 100 cycles | ||
for (i <- 0 until 100){ | ||
poke(c.io.boot, 0) | ||
poke(c.io.test_im_wr, 0) | ||
poke(c.io.test_dm_wr, 0) | ||
expect(c.io.valid, 1) | ||
step(1) | ||
} | ||
|
||
// Check the SW instruction in the DMM | ||
val DmmQ = List(1, 2004, 2004) // The value is decided by "inst.s" | ||
for (i <- 0 until 3){ | ||
poke(c.io.boot, 1) | ||
poke(c.io.test_dm_rd, 1) | ||
poke(c.io.test_dm_addr, i*4) | ||
expect(c.io.test_dm_out, DmmQ(i)) | ||
step(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters