perilus

RISC-V processor built with Chisel
git clone https://git.bradleygannon.com/perilus.git
Log | Files | Refs | Submodules | README

main.scala (4835B)


      1 //> using repository https://central.sonatype.com/repository/maven-snapshots
      2 //> using scala 2.13.17
      3 //> using dep org.chipsalliance::chisel:7.3.0
      4 //> using plugin org.chipsalliance:::chisel-plugin:7.3.0
      5 //> using options -unchecked -deprecation -language:reflectiveCalls -feature -Xcheckinit
      6 //> using options -Xfatal-warnings -Ywarn-dead-code -Ywarn-unused -Ymacro-annotations
      7 
      8 package com.rinthyAi.perilus.main
      9 
     10 import chisel3._
     11 import chisel3.util._
     12 import _root_.circt.stage.ChiselStage
     13 import scala.collection.mutable.ArrayBuffer
     14 import scala.io.Source
     15 
     16 import com.rinthyAi.perilus.alu._
     17 import com.rinthyAi.perilus.extendUnit._
     18 import com.rinthyAi.perilus.memory._
     19 import com.rinthyAi.perilus.registerFile._
     20 import com.rinthyAi.perilus.controlUnit._
     21 
     22 class Perilus(
     23     initRegs: String = "",
     24     initMem: String = "",
     25     withDebug: Boolean = false
     26 ) extends Module {
     27   val width = 32.W
     28   val memorySizeWords = if (initMem.nonEmpty) {
     29     Source.fromFile(initMem).getLines().size
     30   } else { 1048576 }
     31 
     32   val io = IO(new Bundle {
     33     val memory = Module(new Memory(memorySizeWords, width, initMem, withDebug))
     34     val registerFile = Module(new RegisterFile(width, initRegs, withDebug))
     35     val pc = Output(UInt(width))
     36     val debug =
     37       if (withDebug) Some(new Bundle {
     38         val reg = Input(UInt(5.W))
     39         val regData = Output(UInt(width))
     40         val memAddr = Input(UInt(width))
     41         val memData = Output(Vec(width.get / 8, UInt(8.W)))
     42         val state = Output(ControlUnitState())
     43       })
     44       else None
     45   })
     46 
     47   val alu = Module(new Alu())
     48   val controlUnit = Module(new ControlUnit(withDebug))
     49   val extendUnit = Module(new ExtendUnit())
     50 
     51   io.registerFile.io.debug.foreach(r => {
     52     r.reg := 0.U
     53   })
     54   io.memory.io.debug.foreach(m => {
     55     m.memAddr := 0.U
     56   })
     57   io.debug.foreach(d => {
     58     io.registerFile.io.debug.foreach(r => {
     59       r.reg := d.reg
     60       d.regData := r.regData
     61     })
     62     io.memory.io.debug.foreach(m => {
     63       m.memAddr := d.memAddr
     64       d.memData := m.memData
     65     })
     66     controlUnit.io.debug.foreach(c => {
     67       d.state := c.state
     68     })
     69   })
     70 
     71   val pc = RegInit(0.U(width))
     72   val pcNext = WireDefault(UInt(width), 0.U)
     73   when(controlUnit.io.pcWrite) {
     74     // Mask LSB
     75     pc := pcNext & ~1.U(width)
     76   }
     77 
     78   io.pc := pc
     79 
     80   val oldPc = RegInit(0.U(width))
     81   when(controlUnit.io.irWrite) {
     82     oldPc := pc
     83   }
     84 
     85   val instr = RegInit(0.U(width))
     86   when(controlUnit.io.irWrite) {
     87     instr := io.memory.io.readData
     88   }
     89 
     90   val readDataBuf = RegInit(0.U(width))
     91   readDataBuf := io.memory.io.readData
     92 
     93   val rd1Buf = RegInit(0.U(width))
     94   rd1Buf := io.registerFile.io.rd1
     95   val rd2Buf = RegInit(0.U(width))
     96   rd2Buf := io.registerFile.io.rd2
     97 
     98   val aluOutBuf = RegInit(0.U(width))
     99   aluOutBuf := alu.io.aluResult
    100 
    101   val result = WireDefault(0.U(width))
    102   pcNext := result
    103   switch(controlUnit.io.resultSrc) {
    104     is(ResultSrc.aluOutBuf) {
    105       result := aluOutBuf
    106     }
    107     is(ResultSrc.readDataBuf) {
    108       result := readDataBuf
    109     }
    110     is(ResultSrc.aluResult) {
    111       result := alu.io.aluResult
    112     }
    113     is(ResultSrc.immExt) {
    114       result := extendUnit.io.immExt
    115     }
    116   }
    117 
    118   alu.io.aluControl := controlUnit.io.aluControl
    119   alu.io.srcA := 0.U
    120   alu.io.srcB := 0.U
    121   switch(controlUnit.io.aluSrcA) {
    122     is(AluSrcA.pc) {
    123       alu.io.srcA := pc
    124     }
    125     is(AluSrcA.oldPc) {
    126       alu.io.srcA := oldPc
    127     }
    128     is(AluSrcA.rd1) {
    129       alu.io.srcA := rd1Buf
    130     }
    131   }
    132   switch(controlUnit.io.aluSrcB) {
    133     is(AluSrcB.rd2) {
    134       alu.io.srcB := rd2Buf
    135     }
    136     is(AluSrcB.immExt) {
    137       alu.io.srcB := extendUnit.io.immExt
    138     }
    139     is(AluSrcB.four) {
    140       alu.io.srcB := 4.U
    141     }
    142   }
    143   controlUnit.io.zero := alu.io.zero
    144   controlUnit.io.lessThan := alu.io.lessThan
    145 
    146   val (opcode, opcodeValid) = Opcode.safe(instr(6, 0))
    147   controlUnit.io.op := opcode
    148   controlUnit.io.funct3 := instr(14, 12)
    149   controlUnit.io.funct7_5 := instr(30)
    150 
    151   extendUnit.io.input := instr(31, 7)
    152   extendUnit.io.immSrc := controlUnit.io.immSrc
    153 
    154   when(controlUnit.io.adrSrc) {
    155     io.memory.io.address := result
    156   }.otherwise {
    157     io.memory.io.address := pc
    158   }
    159   io.memory.io.writeData := rd2Buf
    160   io.memory.io.writeEnable := controlUnit.io.memWrite
    161   io.memory.io.dataMask := controlUnit.io.dataMask
    162   io.memory.io.signExtData := controlUnit.io.signExtData
    163 
    164   io.registerFile.io.a1 := instr(19, 15)
    165   io.registerFile.io.a2 := instr(24, 20)
    166   io.registerFile.io.a3 := instr(11, 7)
    167   io.registerFile.io.writeData3 := result
    168   io.registerFile.io.writeEnable3 := controlUnit.io.regWrite
    169 }
    170 
    171 object Perilus extends App {
    172   println(
    173     ChiselStage.emitSystemVerilogFile(
    174       new Perilus,
    175       args = Array("--target-dir", "generated"),
    176       firtoolOpts = Array(
    177         "-disable-all-randomization",
    178         "-strip-debug-info",
    179         "-default-layer-specialization=enable"
    180       )
    181     )
    182   )
    183 }