Skip to content

Commit

Permalink
MultiCycle Top.scala, ALU.scala TopTests and launcher added
Browse files Browse the repository at this point in the history
  • Loading branch information
zavs committed May 15, 2017
1 parent 0d5e8a7 commit ef98af5
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 1 deletion.
3 changes: 3 additions & 0 deletions run-multi.bak.v.sh
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"
9 changes: 9 additions & 0 deletions run-multi.sh
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.
80 changes: 80 additions & 0 deletions src/main/scala/MultiCycle/ALU.scala
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
}
84 changes: 84 additions & 0 deletions src/main/scala/MultiCycle/Top.scala
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))
//...
}
52 changes: 52 additions & 0 deletions src/test/scala/MultiCycle/Launcher.scala
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)
}
}
70 changes: 70 additions & 0 deletions src/test/scala/MultiCycle/TopTests.scala
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)
}
}
2 changes: 1 addition & 1 deletion src/test/scala/SingleCycle/TopTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class TopTests(c: Top) extends PeekPokeTester(c) {
// Initialize the IMM content from file "inst.s",
// which could be dumped from MARS.
def WriteImm () = {
val filename = "inst.s"
val filename = "inst2.s"
var addr = 0
var Inst = 0
for (line <- Source.fromFile(filename).getLines){
Expand Down

0 comments on commit ef98af5

Please sign in to comment.