the below chisel code is a aeq module which has 9 brams and each bram has 256 different location wherei can store 11 bits data in
it.in this aeq module there are 3 registers. they are read counter, write counter, and coloum select counter. the read counter is 8 bit wide and contains the address of the bram location from where it read the 9 bit data from a particular bram location. now there are 9 write counters(8 bits wide), 1 for every
bram.it contains the address of a individual location of a bram and write the date into it.
after the last data is stored in a bram location, the valid bit is set to 1 for that location and rest other location the valid bot is set to 0.
the problem for the chisel code is that 1. this code generate bram memory which takes lut's(look up table) on fpga which consume more space and not practically implementable. i want the code to synthesize pre defined Block Ram on fpga.
2. the 2nd problem is that the synthesize verilog code has dual port write channel for same address location which make it difficult to use as how to manage both port at a single instant. please look upon the problem suggest some solution to it.
this is the chisel code.
//> using scala "2.13.12"
//> using dep "org.chipsalliance::chisel::6.0.0"
//> using plugin "org.chipsalliance:::chisel-plugin::6.0.0"
//> using options "-unchecked", "-deprecation", "-language:reflectiveCalls", "-feature", "-Xcheckinit", "-Xfatal-warnings", "-Ywarn-dead-code", "-Ywarn-unused", "-Ymacro-annotations"
import chisel3._
import chisel3.util._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.freespec.AnyFreeSpec
import java.io.File
import java.io.PrintWriter
class AEQ extends Module {
val io = IO(new Bundle {
val writeEnable = Input(Vec(9, Bool()))
val readEnable = Input(Bool())
val writeData = Input(Vec(9, UInt(9.W)))
val readData = Output(Vec(9, UInt(9.W)))
})
val brams = Seq.fill(9)(SyncReadMem(256, UInt(11.W))) // Each entry is 11 bits: 9 bits for data, 1 bit for valid, 1 bit for end-of-queue
val writeCounters = RegInit(VecInit(Seq.fill(9)(0.U(8.W))))
val readCounter = RegInit(0.U(8.W))
val columnSelectCounter = RegInit(0.U(4.W))
for (i <- 0 until 9){
io.readData(i) := DontCare
}
when(io.readEnable) {
for(i <- 0 until 9) {
val data = brams(i).read(readCounter)
io.readData(i) := data(9, 1) // Extract the 9-bit data
}
readCounter := readCounter + 1.U
when(readCounter === 255.U) {
columnSelectCounter := columnSelectCounter + 1.U
when(columnSelectCounter === 8.U) {
columnSelectCounter := 0.U
}
}
}
for(i <- 0 until 9) {
when(io.writeEnable(i)) {
val data = Cat(0.U(1.W), io.writeData(i), 1.U(1.W)) // Concatenate the valid bit, the data, and the end-of-queue bit
brams(i).write(writeCounters(i), data)
writeCounters(i) := writeCounters(i) + 1.U
when(writeCounters(i) === 255.U) {
val lastData = Cat(1.U(1.W), io.writeData(i), 1.U(1.W)) // Set the end-of-queue bit for the last entry
brams(i).write(writeCounters(i), lastData)
}
}
}
}
object Main extends App {
val verilogString = chisel3.getVerilogString(new AEQ())
val verilogFile = new File("AEQ.v")
val writer = new PrintWriter(verilogFile)
writer.write(verilogString)
writer.close()
}
i tried to generate a single write port to every bram by this chisel code and also tried to generate the block ram memory on the fpga but it is taking lut to generate a memory on fpga and the synthesize verilog code has dual write channel port for a single location in every bram.