From a438edd39637fa20ee1da949b9c6c75e36566459 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Sat, 19 Mar 2022 15:45:17 +0500 Subject: [PATCH 01/11] add prog_uart --- .../peripherals/programmable_uart/PUart.scala | 81 ++++++++++++++++ .../peripherals/programmable_uart/Rx.scala | 95 +++++++++++++++++++ .../programmable_uart/PUartTester.scala | 94 ++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 src/main/scala/jigsaw/peripherals/programmable_uart/PUart.scala create mode 100644 src/main/scala/jigsaw/peripherals/programmable_uart/Rx.scala create mode 100644 src/test/scala/jigsaw/peripherals/programmable_uart/PUartTester.scala diff --git a/src/main/scala/jigsaw/peripherals/programmable_uart/PUart.scala b/src/main/scala/jigsaw/peripherals/programmable_uart/PUart.scala new file mode 100644 index 0000000..12f56b0 --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/programmable_uart/PUart.scala @@ -0,0 +1,81 @@ +package jigsaw.peripherals.programmable_uart + +import chisel3._ +import chisel3.util._ + +class PUart extends Module { + val io = IO(new Bundle { + val isStalled = Input(Bool()) + + val rx_data_o = Output(UInt(32.W)) + val addr_o = Output(UInt(8.W)) + val CLK_PER_BIT = Input(UInt(16.W)) + val rxd = Input(UInt(1.W)) + + val valid = Output(Bool()) + val done = Output(Bool()) + }) + + val regDone = RegInit(false.B) + val count = RegInit(0.U(3.W)) + val regFinalData = RegInit(0.U(32.W)) + val regAddr = RegInit(16383.U(14.W)) + val regValid = RegInit(false.B) + + val rx = Module(new Rx) + + rx.io.CLK_PER_BIT := io.CLK_PER_BIT + rx.io.rxd := io.rxd + + val dataReg = RegInit(0.U(8.W)) + val regLSB1 = RegInit(0.U(8.W)) + val regLSB2 = RegInit(0.U(8.W)) + val regMSB1 = RegInit(0.U(8.W)) + val regMSB2 = RegInit(0.U(8.W)) + + when(io.isStalled && !regDone) { + when(rx.io.valid === 1.U) { + // We get 1 byte of data from the Rx module + // dataReg := rx.io.channel.bits + dataReg := rx.io.data + count := count + 1.U + regValid := false.B + } + } + switch(count) { + is(1.U) { + regLSB1 := dataReg + } + is(2.U) { + regLSB2 := dataReg + } + is(3.U) { + regMSB1 := dataReg + } + is(4.U) { + // Now the 32-Bit data is complete here + val data = Cat(dataReg, regMSB1, regLSB2, regLSB1) + when(data === "h00000fff".U) { + regDone := true.B + regFinalData := 0.U + regAddr := 0.U + regValid := false.B + }.otherwise { + regFinalData := data + regAddr := regAddr + 1.U + regValid := true.B + } + + } + } + + when(count === 4.U) { + count := 0.U + } + + io.addr_o := regAddr + io.rx_data_o := regFinalData + io.valid := regValid + io.done := regDone + +} \ No newline at end of file diff --git a/src/main/scala/jigsaw/peripherals/programmable_uart/Rx.scala b/src/main/scala/jigsaw/peripherals/programmable_uart/Rx.scala new file mode 100644 index 0000000..95d71a1 --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/programmable_uart/Rx.scala @@ -0,0 +1,95 @@ +package jigsaw.peripherals.programmable_uart + +import chisel3._ +import chisel3.util._ +import chisel3.dontTouch + +class Rx extends Module { + val io = IO(new Bundle { + val CLK_PER_BIT = Input(UInt(16.W)) + val rxd = Input(Bits(1.W)) + val valid = Output(Bool()) + val data = Output(Bits(8.W)) + }) + + val CLCK_PER_BIT = dontTouch(Wire(UInt(32.W))) + CLCK_PER_BIT := io.CLK_PER_BIT + + val idle :: start :: data :: stop :: cleanup :: Nil = Enum(5) + val stateReg = RegInit(idle) + + val clockCount = RegInit(0.U(8.W)) + val bitIndex = RegInit(0.U(4.W)) + val validReg = RegInit(0.U(1.W)) + //val dataReg = RegInit(VecInit(Seq.fill(8)(0.U(1.W)))) + val rxReg = RegNext(RegNext(io.rxd, 1.U), 1.U) + val shiftReg = RegInit('A'.U(8.W)) + + switch(stateReg) { + is(idle) { + validReg := 0.U + clockCount := 0.U + bitIndex := 0.U + + when(io.rxd === 0.U) { + stateReg := start + }.otherwise { + stateReg := idle + } + } + + is(start) { + when(clockCount === ((CLCK_PER_BIT - 1.U) / 2.U)) { + when(io.rxd === 0.U) { + clockCount := 0.U + stateReg := data + }.otherwise { + stateReg := idle + } + }.otherwise { + clockCount := clockCount + 1.U + stateReg := start + } + } + + is(data) { + when(clockCount < (CLCK_PER_BIT - 1.U)) { + clockCount := clockCount + 1.U + stateReg := data + }.otherwise { + clockCount := 0.U + shiftReg := Cat(rxReg, shiftReg >> 1) + //dataReg(bitIndex) := io.rxd + + when(bitIndex < 7.U) { + bitIndex := bitIndex + 1.U + stateReg := data + }.otherwise { + bitIndex := 0.U + stateReg := stop + } + } + } + + is(stop) { + when(clockCount < (CLCK_PER_BIT - 1.U)) { + clockCount := clockCount + 1.U + stateReg := stop + }.otherwise { + validReg := 1.U + clockCount := 0.U + stateReg := cleanup + } + } + + is(cleanup) { + stateReg := idle + validReg := 0.U + } + } + + io.data := shiftReg + //io.data := dataReg.asUInt() + io.valid := validReg + +} \ No newline at end of file diff --git a/src/test/scala/jigsaw/peripherals/programmable_uart/PUartTester.scala b/src/test/scala/jigsaw/peripherals/programmable_uart/PUartTester.scala new file mode 100644 index 0000000..669afd6 --- /dev/null +++ b/src/test/scala/jigsaw/peripherals/programmable_uart/PUartTester.scala @@ -0,0 +1,94 @@ +package jigsaw.peripherals.programmable_uart + +import chisel3._ +import chisel3 . util._ +import caravan.bus.tilelink._ +import org.scalatest._ +import chisel3.experimental._ +import chiseltest._ +import chisel3.experimental.BundleLiterals._ +import chiseltest.experimental.TestOptionBuilder._ +import chiseltest.internal.VerilatorBackendAnnotation +// import jigsaw.peripherals.spi._ +// import jigsaw.SpiHarness +// import caravan.bus.wishbone.WishboneConfig +// import caravan.bus.tilelink.TilelinkConfig +import jigsaw.peripherals.programmable_uart.PUart + +class PUartTester extends FreeSpec with ChiselScalatestTester { + + "Programable Uart Tests" in { + test(new PUart()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => + + // poke(c.io.CLK_PER_BIT, 4.U) + c.io.CLK_PER_BIT.poke(4.U) + c.io.isStalled.poke(true.B) + // val bufferedSource = Source.fromFile(filePath) + // val fileData = bufferedSource.getLines.toArray + // We create an array insts by reading the lines from the text file and parsing the string + // as hexadecimal. The parse function does not accept 0x literals so we used substring(2) + // to get rid of the first two characters which are 0x finally "yielding" it into an array. +// val insts = for (i <- fileData) yield java.lang.Long.parseLong(i, 16) + // val insts = for (i <- fileData) yield java.lang.Long.parseLong(i.substring(2), 16) + // closing the opened file + // bufferedSource.close + + // poke(c.io.rxd, 1) + c.io.rxd.poke(1.U) + c.clock.step(10) + val insts = Array(0xf0f0f0f0, 0x0f0f0f0f, 0x00000fff) + for (inst <- insts) { + // val inst = 0xf0f0f0f0 + val half_byte1 = inst & 0x0f // 3 + val half_byte2 = (inst & 0xf0) >> 4 // 1 + val byte1 = (half_byte2 << 4) | half_byte1 // 0x13 + + val half_byte3 = (inst & 0xf00) >> 8 // 1 + val half_byte4 = (inst & 0xf000) >> 12 // 0 + val byte2 = (half_byte4 << 4) | half_byte3 // 0x01 + + val half_byte5 = (inst & 0xf0000) >> 16 // 0 + val half_byte6 = (inst & 0xf00000) >> 20 // 2 + val byte3 = (half_byte6 << 4) | half_byte5 // 0x20 + + val half_byte7 = (inst & 0xf000000) >> 24 // 0 + val half_byte8 = (inst & 0xf0000000) >> 28 // 0 + val byte4 = (half_byte8 << 4) | half_byte7 // 0x00 + + //printf("The instruction is %x".format(byte4)) + pokeUart(byte1.toInt) + pokeUart(byte2.toInt) + pokeUart(byte3.toInt) + pokeUart(byte4.toInt) + } + + def pokeUart(value: Int): Unit = { + + // start bit + // poke(c.io.rxd, 0) + c.io.rxd.poke(0.U) + // step(4) + c.clock.step(4) + // 8 data bits + for (i <- 0 until 8) { + // poke(c.io.rxd, (value >> i) & 0x01) + c.io.rxd.poke(((value >> i) & 0x01).U) + // step(4) + c.clock.step(4) + } + // stop bit + // poke(c.io.rxd, 1) + c.io.rxd.poke(1.U) + // step(4) + c.clock.step(4) + } + // step(200) + c.clock.step(200) + + + + + + } + } +} \ No newline at end of file From a5ae98ad7f1ecab92b913cb891f09af79c9e042d Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Sat, 19 Mar 2022 16:38:01 +0500 Subject: [PATCH 02/11] sram added --- src/main/resources/sram/sram.v | 144 ++++++++++++++++++ src/main/scala/jigsaw/SramHarness.scala | 65 ++++++++ src/main/scala/jigsaw/rams/sram/SRAM1kb.scala | 92 +++++++++++ .../scala/jigsaw/rams/sram/SRAMTests.scala | 52 +++++++ 4 files changed, 353 insertions(+) create mode 100644 src/main/resources/sram/sram.v create mode 100644 src/main/scala/jigsaw/SramHarness.scala create mode 100644 src/main/scala/jigsaw/rams/sram/SRAM1kb.scala create mode 100644 src/test/scala/jigsaw/rams/sram/SRAMTests.scala diff --git a/src/main/resources/sram/sram.v b/src/main/resources/sram/sram.v new file mode 100644 index 0000000..3ee3928 --- /dev/null +++ b/src/main/resources/sram/sram.v @@ -0,0 +1,144 @@ +// SPDX-FileCopyrightText: 2020 fabless Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 + +//`default_nettype none +// OpenRAM SRAM model +// Words: 256 +// Word size: 32 +// Write size: 8 + +module sram #( + parameter NUM_WMASKS = 4, + parameter DATA_WIDTH = 32, + parameter ADDR_WIDTH = 10, + parameter RAM_DEPTH = 1 << ADDR_WIDTH, + // FIXME: This delay is arbitrary. + parameter DELAY = 3, + parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over INITFILE) + parameter IFILE = "" +) +( +/*`ifdef USE_POWER_PINS + vdd, + gnd, +`endif */ +// Port 0: RW + clk0,csb0,web0,wmask0,addr0,din0,dout0, +// Port 1: R + clk1,csb1,addr1,dout1 + ); + + +/*`ifdef USE_POWER_PINS + inout vdd; + inout gnd; +`endif + */ + input clk0; // clock + input csb0; // active low chip select + input web0; // active low write control + input [NUM_WMASKS-1:0] wmask0; // write mask + input [ADDR_WIDTH-1:0] addr0; + input [DATA_WIDTH-1:0] din0; + output [DATA_WIDTH-1:0] dout0; + input clk1; // clock + input csb1; // active low chip select + input [ADDR_WIDTH-1:0] addr1; + output [DATA_WIDTH-1:0] dout1; + + reg csb0_reg; + reg web0_reg; + reg [NUM_WMASKS-1:0] wmask0_reg; + reg [ADDR_WIDTH-1:0] addr0_reg; + reg [DATA_WIDTH-1:0] din0_reg; + reg [DATA_WIDTH-1:0] dout0; + + // All inputs are registers + always @(posedge clk0) + begin + csb0_reg = csb0; + web0_reg = web0; + wmask0_reg = wmask0; + addr0_reg = addr0; + din0_reg = din0; + //dout0 = 32'bx0; +/*`ifdef DBG + if ( !csb0_reg && web0_reg ) + $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]); + if ( !csb0_reg && !web0_reg ) + $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg); +`endif +*/ end + + reg csb1_reg; + reg [ADDR_WIDTH-1:0] addr1_reg; + reg [DATA_WIDTH-1:0] dout1; + + // All inputs are registers + always @(posedge clk1) + begin + csb1_reg = csb1; + addr1_reg = addr1; +//`ifdef DBG +// if (!csb0 && !web0 && !csb1 && (addr0 == addr1)) +// $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1); +// dout1 = 32'bx; +// if ( !csb1_reg ) +// $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]); +//`endif + end +integer i; +reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; +initial + if (IZERO) + for (i=0; i io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.wbMasterTransmitter <> deviceAdapter.io.wbMasterReceiver + hostAdapter.io.wbSlaveReceiver <> deviceAdapter.io.wbSlaveTransmitter + + sram.io.req <> deviceAdapter.io.reqOut + sram.io.rsp <> deviceAdapter.io.rspIn +} + +object SramDriverWB extends App { + implicit val config = WishboneConfig(32,32) +// implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new SramHarness()) +} + + + + +class SramHarnessTL(implicit val config: TilelinkConfig ) extends Module { + val io = IO(new Bundle { + + // bus interconnect interfaces + val req = Flipped(Decoupled(new TLRequest())) + val rsp = Decoupled(new TLResponse()) + + }) + val hostAdapter = Module(new TilelinkHost()) + val deviceAdapter = Module(new TilelinkDevice()) + val sram = Module(new SRAM1kb(new TLRequest(), new TLResponse())) + + hostAdapter.io.reqIn <> io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.tlMasterTransmitter <> deviceAdapter.io.tlMasterReceiver + hostAdapter.io.tlSlaveReceiver <> deviceAdapter.io.tlSlaveTransmitter + + sram.io.req <> deviceAdapter.io.reqOut + sram.io.rsp <> deviceAdapter.io.rspIn + +} + +object SramDriverTL extends App { + implicit val config = TilelinkConfig() +// implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new SramHarnessTL()) +} diff --git a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala new file mode 100644 index 0000000..70e1b39 --- /dev/null +++ b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala @@ -0,0 +1,92 @@ +package jigsaw.rams.sram + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ +import chisel3.util.experimental._ + +import caravan.bus.common.{AbstrRequest, AbstrResponse, BusConfig} + +class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B) extends Module { + val io = IO(new Bundle { + val req = Flipped(Decoupled(gen)) + val rsp = Decoupled(gen1) + }) + + // the register that sends valid along with the data read from memory + // a register is used so that it synchronizes along with the data that comes after one cycle + val validReg = RegInit(false.B) + io.rsp.valid := validReg + io.rsp.bits.error := false.B // assuming memory controller would never return an error + io.req.ready := true.B // assuming we are always ready to accept requests from device + + val rdata = Wire(UInt(32.W)) + + // the memory + val sram = Module(new sram()) + + val clk = WireInit(clock.asUInt()(0)) + + sram.io.clk0 := clk + sram.io.csb0 := 1.B + sram.io.web0 := DontCare + sram.io.wmask0 := DontCare + sram.io.addr0 := DontCare + sram.io.din0 := DontCare + // io.dout0 := a.io.dout0 + + sram.io.clk1 := DontCare + sram.io.csb1 := DontCare + sram.io.addr1 := DontCare + + dontTouch(io.req.valid) + + when(io.req.valid && !io.req.bits.isWrite) { + // READ + // rdata := mem.read(io.req.bits.addrRequest/4.U) + validReg := true.B + sram.io.csb0 := false.B + sram.io.web0 := true.B + sram.io.addr0 := io.req.bits.addrRequest + + rdata := sram.io.dout0 + } .elsewhen(io.req.valid && io.req.bits.isWrite) { + // WRITE + // mem.write(io.req.bits.addrRequest/4.U, wdata, mask) + // validReg := true.B + // rdata map (_ := DontCare) + sram.io.csb0 := false.B + sram.io.web0 := false.B + sram.io.wmask0 := io.req.bits.activeByteLane + sram.io.addr0 := io.req.bits.addrRequest + sram.io.din0 := io.req.bits.dataRequest + validReg := true.B + rdata := DontCare + } .otherwise { + validReg := false.B + // rdata map (_ := DontCare) + rdata := DontCare + } + + io.rsp.bits.dataResponse := rdata +} + +class SRAMIO extends Bundle { + val clk0 = Input(Bool()) + val csb0 = Input(Bool()) + val web0 = Input(Bool()) + val wmask0 = Input(UInt(4.W)) + val addr0 = Input(UInt(10.W)) + val din0 = Input(UInt(32.W)) + val dout0 = Output(UInt(32.W)) + + val clk1 = Input(Bool()) + val csb1 = Input(Bool()) + val addr1 = Input(UInt(10.W)) + val dout1 = Output(UInt(32.W)) + +} +class sram extends BlackBox with HasBlackBoxResource { + val io = IO(new SRAMIO) + addResource("/sram/sram.v") +} \ No newline at end of file diff --git a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala new file mode 100644 index 0000000..e323af1 --- /dev/null +++ b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala @@ -0,0 +1,52 @@ +package jigsaw.rams.sram + +import chisel3._ +import chisel3.util._ +import org.scalatest._ +import chisel3.experimental._ +import chiseltest._ +import chisel3.experimental.BundleLiterals._ +import chiseltest.experimental.TestOptionBuilder._ +import chiseltest.internal.VerilatorBackendAnnotation +// import org.scalatest.flatspec.AnyFlatSpec +import jigsaw.SramHarness +import caravan.bus.wishbone.WishboneConfig +import caravan.bus.tilelink.TilelinkConfig + +class SRAMTests extends FreeSpec with ChiselScalatestTester { + implicit val config = WishboneConfig(32,32) + "SRAM" in { + test(new SramHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => + c.io.req.valid.poke(0.B) + + // c.io.csb0.poke(0.B) + // c.io.web0.poke(0.B) + // c.io.addr0.poke(4.U) + // c.io.din0.poke(8.U) + // c.io.wmask0.poke(15.U) + // // c.clock.step(1) + // // c.io.csb0.poke(1.B) + // c.clock.step(1) + // c.io.csb0.poke(0.B) + // c.io.web0.poke(1.B) + // c.io.addr0.poke(4.U) + // c.clock.step(1) + // c.io.csb0.poke(1.B) + // c.io.web0.poke(0.B) + + // var count = 0 + // while(count != 15){ + // c.io.addr0.poke(count.U) + // c.clock.step(1) + // count += 1 + // } + + + // c.io.addr0.poke(3.U) + // c.clock.step(1) + // c.io.addr0.poke(1.U) + + c.clock.step(100) + } + } +} From 0d1f023aac14734dd0db3e38f8b84579d1df2ea2 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Sat, 26 Mar 2022 20:45:32 +0500 Subject: [PATCH 03/11] timer added as peripheral --- src/main/scala/jigsaw/TimerHarness.scala | 78 ++++++++++++ .../jigsaw/peripherals/timer/Timer.scala | 114 ++++++++++++++++++ .../peripherals/timer/TimerTester.scala | 48 ++++++++ 3 files changed, 240 insertions(+) create mode 100644 src/main/scala/jigsaw/TimerHarness.scala create mode 100644 src/main/scala/jigsaw/peripherals/timer/Timer.scala create mode 100644 src/test/scala/jigsaw/peripherals/timer/TimerTester.scala diff --git a/src/main/scala/jigsaw/TimerHarness.scala b/src/main/scala/jigsaw/TimerHarness.scala new file mode 100644 index 0000000..2e0adee --- /dev/null +++ b/src/main/scala/jigsaw/TimerHarness.scala @@ -0,0 +1,78 @@ +package jigsaw +import caravan.bus.tilelink.{TLRequest, TLResponse, TilelinkConfig, TilelinkDevice, TilelinkHost} +import caravan.bus.wishbone.{WBRequest, WBResponse, WishboneConfig, WishboneDevice, WishboneHost} +import chisel3._ +import chisel3.stage.ChiselStage +import chisel3.util.Decoupled +// import jigsaw.peripherals.spiflash.{Config,Spi} +// import jigsaw.rams.sram._ +import jigsaw.peripherals.timer._ + +class TimerHarness(implicit val config: WishboneConfig ) extends Module { + val io = IO(new Bundle { + + // bus interconnect interfaces + val req = Flipped(Decoupled(new WBRequest())) + val rsp = Decoupled(new WBResponse()) + + val cio_timer_intr_cmp = Output(Bool()) + val cio_timer_intr_ovf = Output(Bool()) + }) + val hostAdapter = Module(new WishboneHost()) + val deviceAdapter = Module(new WishboneDevice()) + val timer = Module(new Timer(new WBRequest(), new WBResponse())) + + hostAdapter.io.reqIn <> io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.wbMasterTransmitter <> deviceAdapter.io.wbMasterReceiver + hostAdapter.io.wbSlaveReceiver <> deviceAdapter.io.wbSlaveTransmitter + + timer.io.req <> deviceAdapter.io.reqOut + timer.io.rsp <> deviceAdapter.io.rspIn + + io.cio_timer_intr_cmp := timer.io.cio_timer_intr_cmp + io.cio_timer_intr_ovf := timer.io.cio_timer_intr_ovf +} + +object TimerDriverWB extends App { + implicit val config = WishboneConfig(32,32) +// implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new TimerHarness()) +} + + + + +class TimerHarnessTL(implicit val config: TilelinkConfig ) extends Module { + val io = IO(new Bundle { + + // bus interconnect interfaces + val req = Flipped(Decoupled(new TLRequest())) + val rsp = Decoupled(new TLResponse()) + + val cio_timer_intr_cmp = Output(Bool()) + val cio_timer_intr_ovf = Output(Bool()) + + }) + val hostAdapter = Module(new TilelinkHost()) + val deviceAdapter = Module(new TilelinkDevice()) + val timer = Module(new Timer(new TLRequest(), new TLResponse())) + + hostAdapter.io.reqIn <> io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.tlMasterTransmitter <> deviceAdapter.io.tlMasterReceiver + hostAdapter.io.tlSlaveReceiver <> deviceAdapter.io.tlSlaveTransmitter + + timer.io.req <> deviceAdapter.io.reqOut + timer.io.rsp <> deviceAdapter.io.rspIn + + io.cio_timer_intr_cmp := timer.io.cio_timer_intr_cmp + io.cio_timer_intr_ovf := timer.io.cio_timer_intr_ovf + +} + +object TimerDriverTL extends App { + implicit val config = TilelinkConfig() +// implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new TimerHarnessTL()) +} diff --git a/src/main/scala/jigsaw/peripherals/timer/Timer.scala b/src/main/scala/jigsaw/peripherals/timer/Timer.scala new file mode 100644 index 0000000..067c2d9 --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/timer/Timer.scala @@ -0,0 +1,114 @@ +package jigsaw.peripherals.timer + +import chisel3._ +import chisel3.util._ +import caravan.bus.common.{AbstrRequest, AbstrResponse} + +class Timer_IO[A <: AbstrRequest, B <: AbstrResponse] (gen: A, gen1: B) extends Bundle{ + + // bus interconnect interfaces + val req = Flipped(Decoupled(gen)) + val rsp = Decoupled(gen1) + + val cio_timer_intr_cmp = Output(Bool()) + val cio_timer_intr_ovf = Output(Bool()) +} + + +// timer in chisel +class Timer[A <: AbstrRequest, B <: AbstrResponse] (gen: A, gen1: B) extends Module{ + val io = IO(new Timer_IO(gen,gen1)) + + // registers + val TimerReg = RegInit(0.U(32.W)) // RO 0x0 + val ControlReg = RegInit(0.U(32.W)) // RW 0x4 + val CompareReg = RegInit(0.U(32.W)) // RW 0x8 + val PreCountReg= RegInit(0.U(32.W)) // RO 0xC + + val maskedData = Wire(Vec(4, UInt(8.W))) + maskedData := io.req.bits.activeByteLane.asTypeOf(Vec(4, Bool())) map (Fill(8,_)) + + io.req.ready := 1.B + io.rsp.valid := 0.B + + // io.cio_timer_intr_cmp := DontCare + + when (io.req.bits.addrRequest(3,0) === 0.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, TimerReg, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .elsewhen (io.req.bits.addrRequest(3,0) === 4.U && io.req.bits.isWrite === 1.B){ + ControlReg := Mux(io.req.valid, io.req.bits.dataRequest & maskedData.asUInt, ControlReg) + + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, io.req.bits.dataRequest, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .elsewhen (io.req.bits.addrRequest(3,0) === 4.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, ControlReg, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .elsewhen (io.req.bits.addrRequest(3,0) === 8.U && io.req.bits.isWrite === 1.B){ + CompareReg := Mux(io.req.valid, io.req.bits.dataRequest & maskedData.asUInt, CompareReg) + + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, io.req.bits.dataRequest, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .elsewhen (io.req.bits.addrRequest(3,0) === 8.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, CompareReg, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .elsewhen (io.req.bits.addrRequest(3,0) === 8.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, PreCountReg, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + } + .otherwise{ + List(io.cio_timer_intr_cmp, io.rsp.valid) map (_ := DontCare) + io.rsp.bits.dataResponse := RegNext(io.req.bits.addrRequest) + } + + val enable = WireInit(ControlReg(0)) + val prescalar = WireInit(ControlReg(31,1)) + + // Prescalar+Timer Logic + when(PreCountReg === 0.U && enable){ + PreCountReg := PreCountReg + 1.U + } + .elsewhen(TimerReg === CompareReg || TimerReg === "hffffffff".U){ + TimerReg := 0.U + } + .elsewhen(PreCountReg === prescalar && enable){ + TimerReg := TimerReg + 1.U + PreCountReg := 0.U + }.elsewhen(PreCountReg < prescalar){ + PreCountReg := PreCountReg + 1.U + } + + // Interupts + io.cio_timer_intr_cmp := Mux(enable, TimerReg === CompareReg, 0.B) + io.cio_timer_intr_ovf := Mux(enable, TimerReg === "hffffffff".U, 0.B) + + + + // Error Logic + val addr_hit = Wire(Vec(4, Bool())) + val timerRegMap = Seq(0,4,8,12) + val wireAddr = WireInit(io.req.bits.addrRequest(3,0)) + val addr_miss = Wire(Bool()) + + def go(min:Int, max:Int):Unit = { + if (min == max){ + return + }else{ + addr_hit(min) := wireAddr === timerRegMap(min).asUInt() + go(min+1, max) + } + } + + go(0,4) + + + addr_miss := ~addr_hit.reduce(_ | _)//~addr_hit.contains(true.B) + when(wireAddr === 0.U & io.req.bits.isWrite){io.rsp.bits.error := RegNext(io.req.valid)} + .elsewhen(wireAddr === 12.U & io.req.bits.isWrite){io.rsp.bits.error := RegNext(io.req.valid)} + .otherwise{io.rsp.bits.error := RegNext(io.req.valid & addr_miss)} +} \ No newline at end of file diff --git a/src/test/scala/jigsaw/peripherals/timer/TimerTester.scala b/src/test/scala/jigsaw/peripherals/timer/TimerTester.scala new file mode 100644 index 0000000..c56acae --- /dev/null +++ b/src/test/scala/jigsaw/peripherals/timer/TimerTester.scala @@ -0,0 +1,48 @@ +package jigsaw.peripherals.timer + +import chisel3._ +import chisel3 . util._ +import caravan.bus.tilelink._ +import org.scalatest._ +import chisel3.experimental._ +import chiseltest._ +import chisel3.experimental.BundleLiterals._ +import chiseltest.experimental.TestOptionBuilder._ +import chiseltest.internal.VerilatorBackendAnnotation +import caravan.bus.wishbone.WishboneConfig +import caravan.bus.tilelink.TilelinkConfig +import jigsaw.peripherals.timer._ +import jigsaw._ +// import TimerHarness + +class TimerTester extends FreeSpec with ChiselScalatestTester { + + "Timer Tests" in { + implicit val config = WishboneConfig(32,32) + // implicit val config = TilelinkConfig() + test(new TimerHarness()) { c => + ///////////Set Tx Register//////////// + c.io.req.bits.addrRequest.poke(8.U) + c.io.req.bits.dataRequest.poke(1.U) + c.io.req.bits.activeByteLane.poke("b1111".U) + c.io.req.bits.isWrite.poke(1.B) + c.io.req.valid.poke(1.B) + c.clock.step(1) + c.io.req.valid.poke(0.B) + // c.clock.step(1) + // c.io.req.bits.addrRequest.poke(4.U) + // c.io.req.bits.dataRequest.poke("b11000".U) + // c.io.req.bits.activeByteLane.poke("b1111".U) + // c.io.req.bits.isWrite.poke(1.B) + // c.io.req.valid.poke(1.B) + c.clock.step(2) + c.io.req.bits.addrRequest.poke(4.U) + c.io.req.bits.dataRequest.poke("b11".U) + c.io.req.bits.activeByteLane.poke("b1111".U) + c.io.req.bits.isWrite.poke(1.B) + c.io.req.valid.poke(1.B) + // c.io.req.valid.poke(0.B) + c.clock.step(200) + } + } +} \ No newline at end of file From 23ff56dedf022cd07c200556e1dd5faa755d5c92 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Fri, 29 Apr 2022 01:36:17 +0500 Subject: [PATCH 04/11] Spi added --- caravan | 2 +- src/main/scala/jigsaw/SpiFlashHarness.scala | 90 ++++++++++ src/main/scala/jigsaw/SpiHarness.scala | 2 +- .../scala/jigsaw/peripherals/spi/Config.scala | 5 + .../jigsaw/peripherals/spi/Protocol.scala | 91 ++++++++++ .../scala/jigsaw/peripherals/spi/Spi.scala | 166 ++++++++++++++++++ .../jigsaw/peripherals/spiflash/Spi.scala | 2 +- .../jigsaw/peripherals/spi/SpiTester.scala | 3 +- 8 files changed, 357 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/jigsaw/SpiFlashHarness.scala create mode 100644 src/main/scala/jigsaw/peripherals/spi/Config.scala create mode 100644 src/main/scala/jigsaw/peripherals/spi/Protocol.scala create mode 100644 src/main/scala/jigsaw/peripherals/spi/Spi.scala diff --git a/caravan b/caravan index 2067408..14ed666 160000 --- a/caravan +++ b/caravan @@ -1 +1 @@ -Subproject commit 2067408c4081e4bdfc728f120353b2558d9273e6 +Subproject commit 14ed666e53540a119914f464dfcad0032b736003 diff --git a/src/main/scala/jigsaw/SpiFlashHarness.scala b/src/main/scala/jigsaw/SpiFlashHarness.scala new file mode 100644 index 0000000..6f9b9f1 --- /dev/null +++ b/src/main/scala/jigsaw/SpiFlashHarness.scala @@ -0,0 +1,90 @@ +package jigsaw +import caravan.bus.tilelink.{TLRequest, TLResponse, TilelinkConfig, TilelinkDevice, TilelinkHost} +import caravan.bus.wishbone.{WBRequest, WBResponse, WishboneConfig, WishboneDevice, WishboneHost} +import chisel3._ +import chisel3.stage.ChiselStage +import chisel3.util.Decoupled +import jigsaw.peripherals.spiflash.{Config,SpiFlash} + +class SpiFlashHarness(implicit val config: WishboneConfig, spiConfig:Config) extends Module { + val io = IO(new Bundle { + + // bus interconnect interfaces + val req = Flipped(Decoupled(new WBRequest())) + val rsp = Decoupled(new WBResponse()) + + // master spi interfaces + val cs_n = Output(Bool()) + val sclk = Output(Bool()) + val mosi = Output(Bool()) + val miso = Input(Bool()) + + }) + val hostAdapter = Module(new WishboneHost()) + val deviceAdapter = Module(new WishboneDevice()) + val spi = Module(new SpiFlash(new WBRequest(), new WBResponse())) + + hostAdapter.io.reqIn <> io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.wbMasterTransmitter <> deviceAdapter.io.wbMasterReceiver + hostAdapter.io.wbSlaveReceiver <> deviceAdapter.io.wbSlaveTransmitter + + spi.io.req <> deviceAdapter.io.reqOut + spi.io.rsp <> deviceAdapter.io.rspIn + + + io.cs_n := spi.io.cs_n + io.sclk := spi.io.sclk + io.mosi := spi.io.mosi + + spi.io.miso := io.miso +} + +object SpiFlashDriverWB extends App { + implicit val config = WishboneConfig(32,32) + implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new SpiFlashHarness()) +} + + + + +class SpiFlashHarnessTL(implicit val config: TilelinkConfig, spiConfig:Config) extends Module { + val io = IO(new Bundle { + + // bus interconnect interfaces + val req = Flipped(Decoupled(new TLRequest())) + val rsp = Decoupled(new TLResponse()) + + // master spi interfaces + val cs_n = Output(Bool()) + val sclk = Output(Bool()) + val mosi = Output(Bool()) + val miso = Input(Bool()) + + }) + val hostAdapter = Module(new TilelinkHost()) + val deviceAdapter = Module(new TilelinkDevice()) + val spi = Module(new SpiFlash(new TLRequest(), new TLResponse())) + + hostAdapter.io.reqIn <> io.req + io.rsp <> hostAdapter.io.rspOut + hostAdapter.io.tlMasterTransmitter <> deviceAdapter.io.tlMasterReceiver + hostAdapter.io.tlSlaveReceiver <> deviceAdapter.io.tlSlaveTransmitter + + spi.io.req <> deviceAdapter.io.reqOut + spi.io.rsp <> deviceAdapter.io.rspIn + + + io.cs_n := spi.io.cs_n + io.sclk := spi.io.sclk + io.mosi := spi.io.mosi + + spi.io.miso := io.miso +} + +object SpiFlashDriverTL extends App { + implicit val config = TilelinkConfig() + implicit val spiConfig = Config() + (new ChiselStage).emitVerilog(new SpiFlashHarnessTL()) +} diff --git a/src/main/scala/jigsaw/SpiHarness.scala b/src/main/scala/jigsaw/SpiHarness.scala index 938f025..9fe7148 100644 --- a/src/main/scala/jigsaw/SpiHarness.scala +++ b/src/main/scala/jigsaw/SpiHarness.scala @@ -4,7 +4,7 @@ import caravan.bus.wishbone.{WBRequest, WBResponse, WishboneConfig, WishboneDevi import chisel3._ import chisel3.stage.ChiselStage import chisel3.util.Decoupled -import jigsaw.peripherals.spiflash.{Config,Spi} +import jigsaw.peripherals.spi.{Config,Spi} class SpiHarness(implicit val config: WishboneConfig, spiConfig:Config) extends Module { val io = IO(new Bundle { diff --git a/src/main/scala/jigsaw/peripherals/spi/Config.scala b/src/main/scala/jigsaw/peripherals/spi/Config.scala new file mode 100644 index 0000000..2ed802d --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/spi/Config.scala @@ -0,0 +1,5 @@ +package jigsaw.peripherals.spi + +case class Config( + DW : Int = 32 +) \ No newline at end of file diff --git a/src/main/scala/jigsaw/peripherals/spi/Protocol.scala b/src/main/scala/jigsaw/peripherals/spi/Protocol.scala new file mode 100644 index 0000000..6b8610f --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/spi/Protocol.scala @@ -0,0 +1,91 @@ +package jigsaw.peripherals.spi + +import chisel3._ +import chisel3.util._ +import chisel3.experimental.ChiselEnum + + +class Protocol_IO(DW:Int) extends Bundle{ + val miso = Input(Bool()) + val mosi = Output(Bool()) + val ss = Output(Bool()) + val sck = Output(Bool()) + val data_in = Flipped(Decoupled(UInt(DW.W))) + val data_out = Decoupled(UInt(DW.W)) + val CPOL = Input(Bool()) + val CPHA = Input(Bool()) + // val config = Input(UInt(DW.W)) + // val resetProtocol = Input(Bool()) +} + +class Protocol(implicit val spiConfig: Config) extends Module{ + val io = IO(new Protocol_IO(spiConfig.DW)) + + val CPOL = WireInit(io.CPOL) + val CPHA = WireInit(io.CPHA) + + val idle :: busy :: Nil = Enum(2) + val state = RegInit(idle) + + val miso_dataReg = RegInit(0.U(spiConfig.DW.W)) + val count = RegInit(0.U(7.W)) + val dataReg = RegInit(0.U((spiConfig.DW*2).W)) + + val clk = WireInit(clock.asUInt()(0)) + io.sck := Mux(state === busy, Mux(CPOL,~clk,clk), 0.B) + // io.sck := Mux(CPOL,~clk,clk) // Mode 1 and 4 + // io.sck := 0.B + + io.data_in.ready := 0.B + io.data_out.valid := 0.B + io.data_out.bits := 0.U + io.ss := 1.B + io.mosi := 0.B + + // Transmission + switch(state){ + is(idle){ + io.data_in.ready := 1.B + when (io.data_in.valid/* & io.data_in.ready*/){ + dataReg := Cat(io.data_in.bits, Fill(32,0.B)) // it should be this + state := busy + // io.data_in.ready := 1.B + // io.ss := 0.B + // dataReg := Cat("b00000011".U,Fill(24,0.B),io.data_in.bits) // Fill should be at the end + // dataReg := Cat(io.data_in.bits,Fill(32,0.B)) + + } + } + is(busy){ + when (count === (spiConfig.DW*2).U){ + io.data_in.ready := 1.B + io.ss := 1.B + state := idle + count := 0.U + }.otherwise{ + io.ss := 0.B + io.mosi := dataReg((spiConfig.DW*2)-1) + dataReg := dataReg << 1 + count := count + 1.U + } + } + } + + // Receiving + val count1 = RegInit(0.U(7.W)) + switch(state){ + is(busy){ + io.ss := 0.B + when (count1 === (spiConfig.DW*2).U /*& io.data_out.ready*/){ + io.data_out.bits := miso_dataReg + io.data_out.valid := 1.B + count1 := 0.U + }.otherwise{ + miso_dataReg := miso_dataReg << 1 | io.miso + count1 := count1 + 1.U + } + } + } +} + + diff --git a/src/main/scala/jigsaw/peripherals/spi/Spi.scala b/src/main/scala/jigsaw/peripherals/spi/Spi.scala new file mode 100644 index 0000000..0d0dbc5 --- /dev/null +++ b/src/main/scala/jigsaw/peripherals/spi/Spi.scala @@ -0,0 +1,166 @@ +package jigsaw.peripherals.spi + +import caravan.bus.common.{AbstrRequest, AbstrResponse} +import chisel3._ +import chisel3.experimental.ChiselEnum +import chisel3.stage.ChiselStage +import chisel3.util.{Cat, Decoupled, Fill, MuxCase, Enum} +import jigsaw.peripherals.spiflash._ + +class Spi_IO[A <: AbstrRequest, B <: AbstrResponse] + (gen: A, gen1: B) extends Bundle{ + + // bus interconnect interfaces + val req = Flipped(Decoupled(gen)) + val rsp = Decoupled(gen1) + + // master spi interfaces + val cs_n = Output(Bool()) + val sclk = Output(Bool()) + val mosi = Output(Bool()) + val miso = Input(Bool()) +} + +class Spi[A <: AbstrRequest, B <: AbstrResponse] + (gen: A, gen1: B)(implicit val spiConfig: Config) extends Module{ + + val io = IO(new Spi_IO(gen, gen1)) + val ControlReg = RegInit("b1100000".U(32.W)) // addr 0x0 + val TxDataReg = RegInit(0.U(32.W)) // addr 0x4 + val TxDataValidReg = RegInit(0.B) + val RxDataReg = RegInit(0.U(32.W)) // addr 0x8 + val RxDataValidReg = RegInit(0.B) + + val maskedData = Wire(Vec(4, UInt(8.W))) + maskedData := io.req.bits.activeByteLane.asTypeOf(Vec(4, Bool())) map (Fill(8,_)) + + io.req.ready := 1.B + io.rsp.valid := 0.B + // io.rsp.bits.ackWrite := 1.B + + when (io.req.bits.addrRequest(3,0) === 0.U && io.req.bits.isWrite === 1.B){ + ControlReg := Mux(io.req.valid, io.req.bits.dataRequest & maskedData.asUInt, ControlReg) + + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, io.req.bits.dataRequest, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + + + // List(io.req.ready, io.rsp.valid) map (_ := 1.B) + // List(io.cs_n, io.sclk, io.mosi) map (_ := DontCare) + } + .elsewhen(io.req.bits.addrRequest(3,0) === 0.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, ControlReg, 0.U)) + io.rsp.valid := RegNext(Mux(io.req.valid, 1.B, 0.U)) + + + // List(io.req.ready, io.rsp.valid) map (_ := 1.B) + // List(io.cs_n, io.sclk, io.mosi) map (_ := DontCare) + } + .elsewhen(io.req.bits.addrRequest(3,0) === 4.U && io.req.bits.isWrite === 1.B){ + // when(ControlReg(4,2) === 0.U){ // READ + // TxDataReg := Mux(io.req.valid, Cat("b00000011".U,(io.req.bits.dataRequest & maskedData.asUInt)(23,0)), 0.U) + // TxDataValidReg := io.req.valid + // } + // .elsewhen(ControlReg(4,2) === 1.U){ // WR_EN + // TxDataReg := Mux(io.req.valid, Cat("b00000110".U, Fill(24,0.B)), 0.U) + // TxDataValidReg := io.req.valid + // } + // .elsewhen(ControlReg(4,2) === 2.U){ // PP_ADDR + // TxDataReg := Mux(io.req.valid, Cat("b00000010".U,(io.req.bits.dataRequest & maskedData.asUInt)(23,0)), 0.U) + // TxDataValidReg := io.req.valid + // } + // .elsewhen(ControlReg(4,2) === 3.U){ // PP_DATA + // TxDataReg := Mux(io.req.valid, io.req.bits.dataRequest & maskedData.asUInt, 0.U) + // TxDataValidReg := io.req.valid + // } + // .elsewhen(ControlReg(4,2) === 4.U){ // WR_DI + // TxDataReg := Mux(io.req.valid, Cat("b00000100".U, Fill(24,0.B)), 0.U) + // TxDataValidReg := io.req.valid + // } + TxDataReg := Mux(io.req.valid, io.req.bits.dataRequest & maskedData.asUInt, 0.U) + TxDataValidReg := io.req.valid + + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, io.req.bits.addrRequest, 0.U)) + io.rsp.valid := RegNext(1.B) + + // List(io.req.ready, io.rsp.valid) map (_ := 1.B) + // List(io.cs_n, io.sclk, io.mosi) map (_ := DontCare) + } + .elsewhen(io.req.bits.addrRequest(3,0) === 4.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, TxDataReg, 0.U)) + io.rsp.valid := RegNext(io.req.valid) + + // List(io.req.ready, io.rsp.valid) map (_ := 1.B) + // List(io.cs_n, io.sclk, io.mosi) map (_ := DontCare) + } + .elsewhen(io.req.bits.addrRequest(3,0) === 8.U && io.req.bits.isWrite === 0.B){ + io.rsp.bits.dataResponse := RegNext(Mux(io.rsp.ready, RxDataReg, 0.U)) + io.rsp.valid := RxDataValidReg + // io.rsp.valid := 1.B + + // List(io.req.ready) map (_ := 1.B) + // List(io.cs_n, io.sclk, io.mosi) map (_ := DontCare) + } + .otherwise{ + // List(io.rsp.bits.error, io.rsp.valid) map (_ := 0.B) + // List(io.rsp.valid) map (_ := 0.B) + List(io.cs_n, io.sclk, io.mosi, io.rsp.valid) map (_ := DontCare) + io.rsp.bits.dataResponse := RegNext(io.req.bits.addrRequest) + } + + // ClockGen + def counter(max: UInt) = { + val x = RegInit(0.asUInt(max.getWidth.W)) + x := Mux(x === max, 0.U, x + 1.U) + x + } + def pulse(n: UInt) = counter(n - 1.U) === 0.U + def toggle(p: Bool) = { + val x = RegInit(false.B) + x := Mux(p, !x, x) + x + } + def clockGen(period: UInt) = toggle(pulse(period >> 1)) + // + + // SPI Protocol Logic + val spiProtocol = Module(new Protocol()) + + spiProtocol.clock := clockGen(ControlReg(31,5)).asClock + spiProtocol.io.data_in.bits := TxDataReg + spiProtocol.io.data_in.valid := TxDataValidReg + spiProtocol.io.CPOL := ControlReg(1) + spiProtocol.io.CPHA := ControlReg(0) + spiProtocol.io.miso := io.miso + spiProtocol.io.data_out.ready := 1.B + List(io.mosi, io.sclk, io.cs_n) zip List(spiProtocol.io.mosi, spiProtocol.io.sck, spiProtocol.io.ss) map (a => a._1 := a._2) + when(spiProtocol.io.data_out.valid){ + RxDataReg := spiProtocol.io.data_out.bits + RxDataValidReg := 1.B + } + // + + // Error Logic + val addr_hit = Wire(Vec(3, Bool())) + val spiRegMap = Seq(0,4,8) + val wireAddr = WireInit(io.req.bits.addrRequest(3,0)) + val addr_miss = Wire(Bool()) + + def go(min:Int, max:Int):Unit = { + if (min == max){ + return + }else{ + addr_hit(min) := wireAddr === spiRegMap(min).asUInt() + go(min+1, max) + } + } + + go(0,3) + + + addr_miss := ~addr_hit.reduce(_ | _)//~addr_hit.contains(true.B) + when(wireAddr === 8.U & io.req.bits.isWrite){io.rsp.bits.error := RegNext(io.req.valid)} + .otherwise{io.rsp.bits.error := RegNext(io.req.valid & addr_miss)} + // + +} diff --git a/src/main/scala/jigsaw/peripherals/spiflash/Spi.scala b/src/main/scala/jigsaw/peripherals/spiflash/Spi.scala index 75262e3..1d22acf 100644 --- a/src/main/scala/jigsaw/peripherals/spiflash/Spi.scala +++ b/src/main/scala/jigsaw/peripherals/spiflash/Spi.scala @@ -21,7 +21,7 @@ class Spi_IO[A <: AbstrRequest, B <: AbstrResponse] val miso = Input(Bool()) } -class Spi[A <: AbstrRequest, B <: AbstrResponse] +class SpiFlash[A <: AbstrRequest, B <: AbstrResponse] (gen: A, gen1: B)(implicit val spiConfig: Config) extends Module{ val io = IO(new Spi_IO(gen, gen1)) diff --git a/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala b/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala index 571af75..71396d0 100644 --- a/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala +++ b/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala @@ -14,6 +14,7 @@ import jigsaw.SpiHarness import caravan.bus.wishbone.WishboneConfig import caravan.bus.tilelink.TilelinkConfig import jigsaw.peripherals.spiflash._ +import jigsaw.peripherals.spi._ class SpiTester extends FreeSpec with ChiselScalatestTester { @@ -53,7 +54,7 @@ class SpiTester extends FreeSpec with ChiselScalatestTester { "Spi Flash" in { implicit val config = WishboneConfig(32,32) // implicit val config = TilelinkConfig() - implicit val spiConfig = jigsaw.peripherals.spiflash.Config() + implicit val spiConfig = jigsaw.peripherals.spi.Config() test(new SpiHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => // c.io.req.bits.addrRequest.poke(0.U) // c.io.req.bits.dataRequest.poke(0.U) From b422e57e76fda2034a8521862456b7ac72af8679 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Fri, 29 Apr 2022 01:40:08 +0500 Subject: [PATCH 05/11] rename file --- .../jigsaw/peripherals/spiflash/{Spi.scala => SpiFlash.scala} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/scala/jigsaw/peripherals/spiflash/{Spi.scala => SpiFlash.scala} (100%) diff --git a/src/main/scala/jigsaw/peripherals/spiflash/Spi.scala b/src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala similarity index 100% rename from src/main/scala/jigsaw/peripherals/spiflash/Spi.scala rename to src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala From cb200a287b3cc3cf4c27e8bdc87ad843bf09b88e Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Mon, 2 May 2022 15:02:38 +0500 Subject: [PATCH 06/11] remove config from spi/spiflash --- src/main/scala/jigsaw/SpiFlashHarness.scala | 8 ++++---- src/main/scala/jigsaw/SpiHarness.scala | 8 ++++---- .../scala/jigsaw/peripherals/spi/Protocol.scala | 14 +++++++------- src/main/scala/jigsaw/peripherals/spi/Spi.scala | 2 +- .../jigsaw/peripherals/spiflash/Protocol.scala | 14 +++++++------- .../jigsaw/peripherals/spiflash/SpiFlash.scala | 2 +- .../scala/jigsaw/peripherals/spi/SpiTester.scala | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/scala/jigsaw/SpiFlashHarness.scala b/src/main/scala/jigsaw/SpiFlashHarness.scala index 6f9b9f1..6aa609c 100644 --- a/src/main/scala/jigsaw/SpiFlashHarness.scala +++ b/src/main/scala/jigsaw/SpiFlashHarness.scala @@ -6,7 +6,7 @@ import chisel3.stage.ChiselStage import chisel3.util.Decoupled import jigsaw.peripherals.spiflash.{Config,SpiFlash} -class SpiFlashHarness(implicit val config: WishboneConfig, spiConfig:Config) extends Module { +class SpiFlashHarness(implicit val config: WishboneConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -42,14 +42,14 @@ class SpiFlashHarness(implicit val config: WishboneConfig, spiConfig:Config) ext object SpiFlashDriverWB extends App { implicit val config = WishboneConfig(32,32) - implicit val spiConfig = Config() + // implicit val spiConfig = Config() (new ChiselStage).emitVerilog(new SpiFlashHarness()) } -class SpiFlashHarnessTL(implicit val config: TilelinkConfig, spiConfig:Config) extends Module { +class SpiFlashHarnessTL(implicit val config: TilelinkConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -85,6 +85,6 @@ class SpiFlashHarnessTL(implicit val config: TilelinkConfig, spiConfig:Config) e object SpiFlashDriverTL extends App { implicit val config = TilelinkConfig() - implicit val spiConfig = Config() + // implicit val spiConfig = Config() (new ChiselStage).emitVerilog(new SpiFlashHarnessTL()) } diff --git a/src/main/scala/jigsaw/SpiHarness.scala b/src/main/scala/jigsaw/SpiHarness.scala index 9fe7148..a9355dd 100644 --- a/src/main/scala/jigsaw/SpiHarness.scala +++ b/src/main/scala/jigsaw/SpiHarness.scala @@ -6,7 +6,7 @@ import chisel3.stage.ChiselStage import chisel3.util.Decoupled import jigsaw.peripherals.spi.{Config,Spi} -class SpiHarness(implicit val config: WishboneConfig, spiConfig:Config) extends Module { +class SpiHarness(implicit val config: WishboneConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -42,14 +42,14 @@ class SpiHarness(implicit val config: WishboneConfig, spiConfig:Config) extends object SpiDriverWB extends App { implicit val config = WishboneConfig(32,32) - implicit val spiConfig = Config() + // implicit val spiConfig = Config() (new ChiselStage).emitVerilog(new SpiHarness()) } -class SpiHarnessTL(implicit val config: TilelinkConfig, spiConfig:Config) extends Module { +class SpiHarnessTL(implicit val config: TilelinkConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -85,6 +85,6 @@ class SpiHarnessTL(implicit val config: TilelinkConfig, spiConfig:Config) extend object SpiDriverTL extends App { implicit val config = TilelinkConfig() - implicit val spiConfig = Config() + // implicit val spiConfig = Config() (new ChiselStage).emitVerilog(new SpiHarnessTL()) } diff --git a/src/main/scala/jigsaw/peripherals/spi/Protocol.scala b/src/main/scala/jigsaw/peripherals/spi/Protocol.scala index 6b8610f..d852892 100644 --- a/src/main/scala/jigsaw/peripherals/spi/Protocol.scala +++ b/src/main/scala/jigsaw/peripherals/spi/Protocol.scala @@ -18,8 +18,8 @@ class Protocol_IO(DW:Int) extends Bundle{ // val resetProtocol = Input(Bool()) } -class Protocol(implicit val spiConfig: Config) extends Module{ - val io = IO(new Protocol_IO(spiConfig.DW)) +class Protocol(val DW:Int = 32) extends Module{ + val io = IO(new Protocol_IO(DW)) val CPOL = WireInit(io.CPOL) val CPHA = WireInit(io.CPHA) @@ -27,9 +27,9 @@ class Protocol(implicit val spiConfig: Config) extends Module{ val idle :: busy :: Nil = Enum(2) val state = RegInit(idle) - val miso_dataReg = RegInit(0.U(spiConfig.DW.W)) + val miso_dataReg = RegInit(0.U(DW.W)) val count = RegInit(0.U(7.W)) - val dataReg = RegInit(0.U((spiConfig.DW*2).W)) + val dataReg = RegInit(0.U((DW*2).W)) val clk = WireInit(clock.asUInt()(0)) io.sck := Mux(state === busy, Mux(CPOL,~clk,clk), 0.B) @@ -57,14 +57,14 @@ class Protocol(implicit val spiConfig: Config) extends Module{ } } is(busy){ - when (count === (spiConfig.DW*2).U){ + when (count === (DW*2).U){ io.data_in.ready := 1.B io.ss := 1.B state := idle count := 0.U }.otherwise{ io.ss := 0.B - io.mosi := dataReg((spiConfig.DW*2)-1) + io.mosi := dataReg((DW*2)-1) dataReg := dataReg << 1 count := count + 1.U } @@ -76,7 +76,7 @@ class Protocol(implicit val spiConfig: Config) extends Module{ switch(state){ is(busy){ io.ss := 0.B - when (count1 === (spiConfig.DW*2).U /*& io.data_out.ready*/){ + when (count1 === (DW*2).U /*& io.data_out.ready*/){ io.data_out.bits := miso_dataReg io.data_out.valid := 1.B count1 := 0.U diff --git a/src/main/scala/jigsaw/peripherals/spi/Spi.scala b/src/main/scala/jigsaw/peripherals/spi/Spi.scala index 0d0dbc5..344db87 100644 --- a/src/main/scala/jigsaw/peripherals/spi/Spi.scala +++ b/src/main/scala/jigsaw/peripherals/spi/Spi.scala @@ -22,7 +22,7 @@ class Spi_IO[A <: AbstrRequest, B <: AbstrResponse] } class Spi[A <: AbstrRequest, B <: AbstrResponse] - (gen: A, gen1: B)(implicit val spiConfig: Config) extends Module{ + (gen: A, gen1: B) extends Module{ val io = IO(new Spi_IO(gen, gen1)) val ControlReg = RegInit("b1100000".U(32.W)) // addr 0x0 diff --git a/src/main/scala/jigsaw/peripherals/spiflash/Protocol.scala b/src/main/scala/jigsaw/peripherals/spiflash/Protocol.scala index 1c535d0..5cda432 100644 --- a/src/main/scala/jigsaw/peripherals/spiflash/Protocol.scala +++ b/src/main/scala/jigsaw/peripherals/spiflash/Protocol.scala @@ -18,8 +18,8 @@ class Protocol_IO(DW:Int) extends Bundle{ // val resetProtocol = Input(Bool()) } -class Protocol(implicit val spiConfig: Config) extends Module{ - val io = IO(new Protocol_IO(spiConfig.DW)) +class Protocol(val DW:Int = 32) extends Module{ + val io = IO(new Protocol_IO(DW)) val CPOL = WireInit(io.CPOL) val CPHA = WireInit(io.CPHA) @@ -27,9 +27,9 @@ class Protocol(implicit val spiConfig: Config) extends Module{ val idle :: busy :: Nil = Enum(2) val state = RegInit(idle) - val miso_dataReg = RegInit(0.U(spiConfig.DW.W)) + val miso_dataReg = RegInit(0.U(DW.W)) val count = RegInit(0.U(7.W)) - val dataReg = RegInit(0.U((spiConfig.DW*2).W)) + val dataReg = RegInit(0.U((DW*2).W)) val clk = WireInit(clock.asUInt()(0)) io.sck := Mux(state === busy, Mux(CPOL,~clk,clk), 0.B) @@ -57,14 +57,14 @@ class Protocol(implicit val spiConfig: Config) extends Module{ } } is(busy){ - when (count === (spiConfig.DW*2).U){ + when (count === (DW*2).U){ io.data_in.ready := 1.B io.ss := 1.B state := idle count := 0.U }.otherwise{ io.ss := 0.B - io.mosi := dataReg((spiConfig.DW*2)-1) + io.mosi := dataReg((DW*2)-1) dataReg := dataReg << 1 count := count + 1.U } @@ -76,7 +76,7 @@ class Protocol(implicit val spiConfig: Config) extends Module{ switch(state){ is(busy){ io.ss := 0.B - when (count1 === (spiConfig.DW*2).U /*& io.data_out.ready*/){ + when (count1 === (DW*2).U /*& io.data_out.ready*/){ io.data_out.bits := miso_dataReg io.data_out.valid := 1.B count1 := 0.U diff --git a/src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala b/src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala index 1d22acf..4b629d0 100644 --- a/src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala +++ b/src/main/scala/jigsaw/peripherals/spiflash/SpiFlash.scala @@ -22,7 +22,7 @@ class Spi_IO[A <: AbstrRequest, B <: AbstrResponse] } class SpiFlash[A <: AbstrRequest, B <: AbstrResponse] - (gen: A, gen1: B)(implicit val spiConfig: Config) extends Module{ + (gen: A, gen1: B) extends Module{ val io = IO(new Spi_IO(gen, gen1)) val ControlReg = RegInit("b1100000".U(32.W)) // addr 0x0 diff --git a/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala b/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala index 71396d0..7a6ff58 100644 --- a/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala +++ b/src/test/scala/jigsaw/peripherals/spi/SpiTester.scala @@ -54,7 +54,7 @@ class SpiTester extends FreeSpec with ChiselScalatestTester { "Spi Flash" in { implicit val config = WishboneConfig(32,32) // implicit val config = TilelinkConfig() - implicit val spiConfig = jigsaw.peripherals.spi.Config() + // implicit val spiConfig = jigsaw.peripherals.spi.Config() test(new SpiHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => // c.io.req.bits.addrRequest.poke(0.U) // c.io.req.bits.dataRequest.poke(0.U) From f8621963a919a127c2cc2e935d64cf78b25a3a95 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Wed, 11 May 2022 11:22:43 +0500 Subject: [PATCH 07/11] IFILE path added --- src/main/scala/jigsaw/SramHarness.scala | 12 ++++---- src/main/scala/jigsaw/rams/sram/SRAM1kb.scala | 12 ++++---- .../scala/jigsaw/rams/sram/SRAMTests.scala | 28 +++++++++++++------ 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/scala/jigsaw/SramHarness.scala b/src/main/scala/jigsaw/SramHarness.scala index f43a1be..8322e6f 100644 --- a/src/main/scala/jigsaw/SramHarness.scala +++ b/src/main/scala/jigsaw/SramHarness.scala @@ -7,7 +7,7 @@ import chisel3.util.Decoupled // import jigsaw.peripherals.spiflash.{Config,Spi} import jigsaw.rams.sram._ -class SramHarness(implicit val config: WishboneConfig ) extends Module { +class SramHarness(programFile:Option[String])(implicit val config: WishboneConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -16,7 +16,7 @@ class SramHarness(implicit val config: WishboneConfig ) extends Module { }) val hostAdapter = Module(new WishboneHost()) val deviceAdapter = Module(new WishboneDevice()) - val sram = Module(new SRAM1kb(new WBRequest(), new WBResponse())) + val sram = Module(new SRAM1kb(new WBRequest(), new WBResponse())(programFile)) hostAdapter.io.reqIn <> io.req io.rsp <> hostAdapter.io.rspOut @@ -30,13 +30,13 @@ class SramHarness(implicit val config: WishboneConfig ) extends Module { object SramDriverWB extends App { implicit val config = WishboneConfig(32,32) // implicit val spiConfig = Config() - (new ChiselStage).emitVerilog(new SramHarness()) + (new ChiselStage).emitVerilog(new SramHarness(None)) } -class SramHarnessTL(implicit val config: TilelinkConfig ) extends Module { +class SramHarnessTL(programFile:Option[String])(implicit val config: TilelinkConfig ) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -46,7 +46,7 @@ class SramHarnessTL(implicit val config: TilelinkConfig ) extends Module { }) val hostAdapter = Module(new TilelinkHost()) val deviceAdapter = Module(new TilelinkDevice()) - val sram = Module(new SRAM1kb(new TLRequest(), new TLResponse())) + val sram = Module(new SRAM1kb(new TLRequest(), new TLResponse())(programFile)) hostAdapter.io.reqIn <> io.req io.rsp <> hostAdapter.io.rspOut @@ -61,5 +61,5 @@ class SramHarnessTL(implicit val config: TilelinkConfig ) extends Module { object SramDriverTL extends App { implicit val config = TilelinkConfig() // implicit val spiConfig = Config() - (new ChiselStage).emitVerilog(new SramHarnessTL()) + (new ChiselStage).emitVerilog(new SramHarnessTL(None)) } diff --git a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala index 70e1b39..a655f22 100644 --- a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala +++ b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala @@ -7,7 +7,7 @@ import chisel3.util.experimental._ import caravan.bus.common.{AbstrRequest, AbstrResponse, BusConfig} -class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B) extends Module { +class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val programFile:Option[String] ) extends Module { val io = IO(new Bundle { val req = Flipped(Decoupled(gen)) val rsp = Decoupled(gen1) @@ -23,7 +23,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B) extends Mo val rdata = Wire(UInt(32.W)) // the memory - val sram = Module(new sram()) + val sram = Module(new sram(programFile)) val clk = WireInit(clock.asUInt()(0)) @@ -86,7 +86,9 @@ class SRAMIO extends Bundle { val dout1 = Output(UInt(32.W)) } -class sram extends BlackBox with HasBlackBoxResource { - val io = IO(new SRAMIO) - addResource("/sram/sram.v") +class sram(programFile:Option[String] ) extends BlackBox( + Map("IFILE" -> {if (programFile.isDefined) programFile.get else ""}) + ) with HasBlackBoxResource { + val io = IO(new SRAMIO) + addResource("/sram/sram.v") } \ No newline at end of file diff --git a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala index e323af1..b39488f 100644 --- a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala +++ b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala @@ -14,10 +14,20 @@ import caravan.bus.wishbone.WishboneConfig import caravan.bus.tilelink.TilelinkConfig class SRAMTests extends FreeSpec with ChiselScalatestTester { + + // def getFile: Option[String] = { + // if (scalaTestContext.value.get.configMap.contains("memFile")) { + // Some(scalaTestContext.value.get.configMap("memFile").toString) + // } else { + // None + // } + // } + implicit val config = WishboneConfig(32,32) "SRAM" in { - test(new SramHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => - c.io.req.valid.poke(0.B) + val programFile = Some("//home//talha//abc.txt") + test(new SramHarness(programFile))/*.withAnnotations(Seq(VerilatorBackendAnnotation))*/ { c => + c.io.req.valid.poke(1.B) // c.io.csb0.poke(0.B) // c.io.web0.poke(0.B) @@ -34,12 +44,14 @@ class SRAMTests extends FreeSpec with ChiselScalatestTester { // c.io.csb0.poke(1.B) // c.io.web0.poke(0.B) - // var count = 0 - // while(count != 15){ - // c.io.addr0.poke(count.U) - // c.clock.step(1) - // count += 1 - // } + var count = 0 + while(count != 15){ + c.io.req.bits.addrRequest.poke(count.U) + c.io.req.bits.dataRequest.poke(count.U) + c.io.req.bits.isWrite.poke(1.B) + c.clock.step(1) + count += 1 + } // c.io.addr0.poke(3.U) From c7cc4b8836a31181446f10826aa8bcc529eb896f Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Wed, 11 May 2022 17:04:56 +0500 Subject: [PATCH 08/11] SRAM update --- src/main/resources/sram/sram.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/sram/sram.v b/src/main/resources/sram/sram.v index 3ee3928..279697a 100644 --- a/src/main/resources/sram/sram.v +++ b/src/main/resources/sram/sram.v @@ -105,7 +105,7 @@ initial if (IZERO) for (i=0; i Date: Fri, 13 May 2022 18:03:53 +0500 Subject: [PATCH 09/11] addr logic fixed --- src/main/scala/jigsaw/rams/sram/SRAM1kb.scala | 4 +- .../scala/jigsaw/rams/sram/SRAMTests.scala | 49 ++++++++++++------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala index a655f22..2a37bbd 100644 --- a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala +++ b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala @@ -47,7 +47,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra validReg := true.B sram.io.csb0 := false.B sram.io.web0 := true.B - sram.io.addr0 := io.req.bits.addrRequest + sram.io.addr0 := io.req.bits.addrRequest/4.U rdata := sram.io.dout0 } .elsewhen(io.req.valid && io.req.bits.isWrite) { @@ -58,7 +58,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra sram.io.csb0 := false.B sram.io.web0 := false.B sram.io.wmask0 := io.req.bits.activeByteLane - sram.io.addr0 := io.req.bits.addrRequest + sram.io.addr0 := io.req.bits.addrRequest/4.U sram.io.din0 := io.req.bits.dataRequest validReg := true.B rdata := DontCare diff --git a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala index b39488f..b52c038 100644 --- a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala +++ b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala @@ -15,19 +15,32 @@ import caravan.bus.tilelink.TilelinkConfig class SRAMTests extends FreeSpec with ChiselScalatestTester { - // def getFile: Option[String] = { - // if (scalaTestContext.value.get.configMap.contains("memFile")) { - // Some(scalaTestContext.value.get.configMap("memFile").toString) - // } else { - // None - // } - // } + def getFile: Option[String] = { + if (scalaTestContext.value.get.configMap.contains("memFile")) { + Some(scalaTestContext.value.get.configMap("memFile").toString) + } else { + None + } + } implicit val config = WishboneConfig(32,32) "SRAM" in { - val programFile = Some("//home//talha//abc.txt") - test(new SramHarness(programFile))/*.withAnnotations(Seq(VerilatorBackendAnnotation))*/ { c => + // val programFile = Some("/home/talha/inst") + val programFile = getFile + // test(new SramHarness(programFile))/*.withAnnotations(Seq(VerilatorBackendAnnotation))*/ { c => + test(new SramHarness(programFile)).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => + c.io.req.valid.poke(1.B) + c.io.req.bits.addrRequest.poke(3.U) + c.io.req.bits.dataRequest.poke("h12345678".U) + c.io.req.bits.activeByteLane.poke("b1000".U) + c.io.req.bits.isWrite.poke(1.B) + c.clock.step(1) + c.io.req.valid.poke(0.B) + c.clock.step(1) c.io.req.valid.poke(1.B) + c.io.req.bits.isWrite.poke(0.B) + c.io.req.bits.addrRequest.poke(3.U) + // c.io.csb0.poke(0.B) // c.io.web0.poke(0.B) @@ -44,16 +57,16 @@ class SRAMTests extends FreeSpec with ChiselScalatestTester { // c.io.csb0.poke(1.B) // c.io.web0.poke(0.B) - var count = 0 - while(count != 15){ - c.io.req.bits.addrRequest.poke(count.U) - c.io.req.bits.dataRequest.poke(count.U) - c.io.req.bits.isWrite.poke(1.B) - c.clock.step(1) - count += 1 - } + // var count = 0 + // while(count != 15){ + // c.io.req.bits.addrRequest.poke(count.U) + // // c.io.req.bits.dataRequest.poke(count.U) + // c.io.req.bits.isWrite.poke(0.B) + // c.clock.step(10) + // count += 1 + // } - + // c.io.req.bits.isWrite.poke(0.B) // c.io.addr0.poke(3.U) // c.clock.step(1) // c.io.addr0.poke(1.U) From 7029e29014a25574de9f912f9343c9f6b0009f5a Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Wed, 18 May 2022 16:17:55 +0500 Subject: [PATCH 10/11] Address issue reverted --- src/main/scala/jigsaw/rams/sram/SRAM1kb.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala index 2a37bbd..a655f22 100644 --- a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala +++ b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala @@ -47,7 +47,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra validReg := true.B sram.io.csb0 := false.B sram.io.web0 := true.B - sram.io.addr0 := io.req.bits.addrRequest/4.U + sram.io.addr0 := io.req.bits.addrRequest rdata := sram.io.dout0 } .elsewhen(io.req.valid && io.req.bits.isWrite) { @@ -58,7 +58,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra sram.io.csb0 := false.B sram.io.web0 := false.B sram.io.wmask0 := io.req.bits.activeByteLane - sram.io.addr0 := io.req.bits.addrRequest/4.U + sram.io.addr0 := io.req.bits.addrRequest sram.io.din0 := io.req.bits.dataRequest validReg := true.B rdata := DontCare From 27d8221e33dab103c7d87817a887436f62d6dbe2 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Fri, 20 May 2022 14:48:30 +0500 Subject: [PATCH 11/11] Initilize addr width param in sram --- src/main/scala/jigsaw/SramHarness.scala | 8 ++++---- src/main/scala/jigsaw/rams/sram/SRAM1kb.scala | 17 +++++++++-------- src/test/scala/jigsaw/rams/sram/SRAMTests.scala | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/scala/jigsaw/SramHarness.scala b/src/main/scala/jigsaw/SramHarness.scala index 8322e6f..d0fbc02 100644 --- a/src/main/scala/jigsaw/SramHarness.scala +++ b/src/main/scala/jigsaw/SramHarness.scala @@ -7,7 +7,7 @@ import chisel3.util.Decoupled // import jigsaw.peripherals.spiflash.{Config,Spi} import jigsaw.rams.sram._ -class SramHarness(programFile:Option[String])(implicit val config: WishboneConfig) extends Module { +class SramHarness(programFile:Option[String], val AW:Int = 10)(implicit val config: WishboneConfig) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -16,7 +16,7 @@ class SramHarness(programFile:Option[String])(implicit val config: WishboneConfi }) val hostAdapter = Module(new WishboneHost()) val deviceAdapter = Module(new WishboneDevice()) - val sram = Module(new SRAM1kb(new WBRequest(), new WBResponse())(programFile)) + val sram = Module(new SRAM1kb(new WBRequest(), new WBResponse())(programFile, AW)) hostAdapter.io.reqIn <> io.req io.rsp <> hostAdapter.io.rspOut @@ -36,7 +36,7 @@ object SramDriverWB extends App { -class SramHarnessTL(programFile:Option[String])(implicit val config: TilelinkConfig ) extends Module { +class SramHarnessTL(programFile:Option[String], val AW:Int = 10)(implicit val config: TilelinkConfig ) extends Module { val io = IO(new Bundle { // bus interconnect interfaces @@ -46,7 +46,7 @@ class SramHarnessTL(programFile:Option[String])(implicit val config: TilelinkCon }) val hostAdapter = Module(new TilelinkHost()) val deviceAdapter = Module(new TilelinkDevice()) - val sram = Module(new SRAM1kb(new TLRequest(), new TLResponse())(programFile)) + val sram = Module(new SRAM1kb(new TLRequest(), new TLResponse())(programFile, AW)) hostAdapter.io.reqIn <> io.req io.rsp <> hostAdapter.io.rspOut diff --git a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala index a655f22..fb0a606 100644 --- a/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala +++ b/src/main/scala/jigsaw/rams/sram/SRAM1kb.scala @@ -7,7 +7,7 @@ import chisel3.util.experimental._ import caravan.bus.common.{AbstrRequest, AbstrResponse, BusConfig} -class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val programFile:Option[String] ) extends Module { +class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(programFile:Option[String], val AW:Int = 10) extends Module { val io = IO(new Bundle { val req = Flipped(Decoupled(gen)) val rsp = Decoupled(gen1) @@ -23,7 +23,7 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra val rdata = Wire(UInt(32.W)) // the memory - val sram = Module(new sram(programFile)) + val sram = Module(new sram(programFile=programFile, AW=AW)) val clk = WireInit(clock.asUInt()(0)) @@ -71,24 +71,25 @@ class SRAM1kb[A <: AbstrRequest, B <: AbstrResponse](gen: A, gen1: B)(val progra io.rsp.bits.dataResponse := rdata } -class SRAMIO extends Bundle { +class SRAMIO(AW:Int) extends Bundle { val clk0 = Input(Bool()) val csb0 = Input(Bool()) val web0 = Input(Bool()) val wmask0 = Input(UInt(4.W)) - val addr0 = Input(UInt(10.W)) + val addr0 = Input(UInt(AW.W)) val din0 = Input(UInt(32.W)) val dout0 = Output(UInt(32.W)) val clk1 = Input(Bool()) val csb1 = Input(Bool()) - val addr1 = Input(UInt(10.W)) + val addr1 = Input(UInt(AW.W)) val dout1 = Output(UInt(32.W)) } -class sram(programFile:Option[String] ) extends BlackBox( - Map("IFILE" -> {if (programFile.isDefined) programFile.get else ""}) +class sram(programFile:Option[String], AW:Int) extends BlackBox( + Map("IFILE" -> {if (programFile.isDefined) programFile.get else ""}, + "ADDR_WIDTH" -> AW) ) with HasBlackBoxResource { - val io = IO(new SRAMIO) + val io = IO(new SRAMIO(AW=AW)) addResource("/sram/sram.v") } \ No newline at end of file diff --git a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala index b52c038..9c9ad2a 100644 --- a/src/test/scala/jigsaw/rams/sram/SRAMTests.scala +++ b/src/test/scala/jigsaw/rams/sram/SRAMTests.scala @@ -28,7 +28,7 @@ class SRAMTests extends FreeSpec with ChiselScalatestTester { // val programFile = Some("/home/talha/inst") val programFile = getFile // test(new SramHarness(programFile))/*.withAnnotations(Seq(VerilatorBackendAnnotation))*/ { c => - test(new SramHarness(programFile)).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => + test(new SramHarness(programFile, 10)).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => c.io.req.valid.poke(1.B) c.io.req.bits.addrRequest.poke(3.U) c.io.req.bits.dataRequest.poke("h12345678".U)