Skip to content

Commit

Permalink
multi channel input
Browse files Browse the repository at this point in the history
  • Loading branch information
mpskex committed Mar 26, 2024
1 parent 0adaeca commit 9b12a92
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 17 deletions.
76 changes: 74 additions & 2 deletions src/main/scala/ncore/mmu/memMngUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import chisel3._
import chisel3.util._
import isa.backend._
import ncore._
import ncore.tcm._

class MMUBundle extends Bundle {
val mem_ch = MemChannel()
Expand All @@ -30,19 +31,90 @@ class OffsetGenerator(val n: Int = 8) extends Module {
}
}


class MemoryControlArray(val n: Int = 8) extends Module {
val io = IO(new Bundle {
val ctrl_in_a = Input(Bool())
val ctrl_in_b = Input(Bool())
val offset_inc_in = Input(Bool())
val ctrl_out_a = Output(Vec(n, Bool()))
val ctrl_out_b = Output(Vec(n, Bool()))
val offset_inc_out = Output(Vec((n-1) * (n-1), Bool()))
})
// Assign each element with diagnal control signal
val reg_inc = RegInit(VecInit(Seq.fill(2*n - 3)(0.B)))
val reg_a = RegInit(VecInit(Seq.fill(n)(0.B)))
val reg_b = RegInit(VecInit(Seq.fill(n)(0.B)))

reg_a(0) := io.ctrl_in_a(0)
reg_b(0) := io.ctrl_in_b(0)
for (i <- 1 until n - 1) {
reg_a(i) := reg_a(i-1)
reg_b(i) := reg_b(i-1)
}

for (i <- 0 until n) {
io.ctrl_out_a(i) := reg_a(i)
io.ctrl_out_b(i) := reg_b(i)
}

reg_inc(0) := io.offset_inc_in
for (i <- 0 until 2 * n - 3) {
reg_inc(i) := reg_inc(i - 1)
}
for (i <- 0 until n - 1) {
for (j <- 0 until n - 1) {
io.offset_inc_out(n * i + j) := reg_inc(i + j)
}
}
}

/**
* This is the neural core design
*/
class MemoryManageUnit(
val n: Int = 8, val nbits: Int = 8, val addr_width: Int = 24
val n: Int = 8,
val nbits: Int = 8,
val word_size: Int = 4,
val size: Int = 4096
) extends Module {
val io = IO(new Bundle {
val base_addr = Input(Vec(n, UInt(24.W)))
val base_addr = Input(UInt(log2Ceil(size).W))
val ctrl = Input(Vec(n * n, new MMUBundle()))
val out_a = Output(Vec(n * n, UInt(32.W)))
val out_b = Output(Vec(n * n, UInt(32.W)))
})

val offsetgen_a = new OffsetGenerator(n)
val offsetgen_b = new OffsetGenerator(n)

val mem = new DetachableTCM(n, word_size, size, 2)

// Create 2d register for horizontal & vertical
val reg_h = RegInit(VecInit(Seq.fill((n - 1) * n)(0.U(nbits.W))))
val reg_v = RegInit(VecInit(Seq.fill((n - 1) * n)(0.U(nbits.W))))

for (i <- 0 until n){
for (j <- 0 until n) {
// ==== INPUT ====
// vertical
if (i==0) {
mem.io.r_addr(0)(j) := io.base_addr + offsetgen_b.io.out(j)
} else {
mem.io.r_addr(0)(n * i + j) := reg_v(n * (i - 1) + j)
}
if (i < n - 1 && j < n)
reg_v(n * i + j) := mem.io.r_addr(0)(n * i + j)

// horizontal
if (j==0) {
mem.io.r_addr(1)(n * i) := io.base_addr + offsetgen_a.io.out(i)
} else {
mem.io.r_addr(1)(n * i + j) := reg_h((n - 1) * i + (j - 1))
}
if (i < n && j < n - 1)
reg_h((n - 1) * i + j) := mem.io.r_addr(1)(n * i + j)
}
}

}
20 changes: 13 additions & 7 deletions src/main/scala/ncore/tcm/tightCpldMem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ class TCMCell(val nbits: Int = 8) extends Module {

class TCMBlock(val n: Int = 8,
val size: Int = 4096,
val rd_ch_num: Int = 2,
val nbits: Int = 8
) extends Module {
val io = IO(
new Bundle {
val d_in = Input(Vec(n * n, UInt(nbits.W)))
val d_out = Output(Vec(n * n, UInt(nbits.W)))
val r_addr = Input(Vec(n * n, UInt(log2Ceil(size).W)))
val d_out = Output(Vec(rd_ch_num, Vec(n * n, UInt(nbits.W))))
val r_addr = Input(Vec(rd_ch_num, Vec(n * n, UInt(log2Ceil(size).W))))
val w_addr = Input(Vec(n * n, UInt(log2Ceil(size).W)))
val en_wr = Input(Bool())
}
Expand All @@ -47,7 +48,9 @@ class TCMBlock(val n: Int = 8,
//TODO: add read & write conflict check

for (i <- 0 until n * n) {
io.d_out(i) := cells_io(io.r_addr(i)).d_out
for (k <- 0 until rd_ch_num) {
io.d_out(k)(i) := cells_io(io.r_addr(k)(i)).d_out
}
when (io.en_wr) {
cells_io(io.w_addr(i)).en_wr := io.en_wr
cells_io(io.w_addr(i)).d_in := io.d_in(i)
Expand All @@ -60,22 +63,25 @@ class DetachableTCM(
val n: Int = 8,
val nblocks: Int = 4,
val size: Int = 4096,
val rd_ch_num: Int = 2,
) extends Module {
val io = IO(new Bundle {
val d_in = Input(Vec(n * n, Vec(nblocks, UInt(8.W))))
val d_out = Output(Vec(n * n, Vec(nblocks, UInt(8.W))))
val r_addr = Input(Vec(n * n, UInt(log2Ceil(size).W)))
val d_out = Output(Vec(rd_ch_num, Vec(n * n, Vec(nblocks, UInt(8.W)))))
val r_addr = Input(Vec(rd_ch_num, Vec(n * n, UInt(log2Ceil(size).W))))
val w_addr = Input(Vec(n * n, UInt(log2Ceil(size).W)))
val en_wr = Input(Bool())
})

val tcm_blocks_io = VecInit(Seq.fill(nblocks) {
Module(new TCMBlock(n, size, 8)).io})
Module(new TCMBlock(n, size, rd_ch_num, 8)).io})

for (i <- 0 until nblocks) {
tcm_blocks_io(i).en_wr := io.en_wr
for (j <- 0 until n) {
tcm_blocks_io(i).r_addr(j) := io.r_addr(j)
for (k <- 0 until rd_ch_num) {
tcm_blocks_io(i).r_addr(k)(j) := io.r_addr(k)(j)
}
tcm_blocks_io(i).w_addr(j) := io.w_addr(j)
tcm_blocks_io(i).d_in(j) := io.d_in(j)(i)
io.d_out(j)(i) := tcm_blocks_io(i).d_out(j)
Expand Down
60 changes: 52 additions & 8 deletions src/test/scala/ncore/tcm/TCMSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class TCMSpec extends AnyFlatSpec with ChiselScalatestTester {
}

"TCM Block" should "write on signal and read anytime" in {
test(new TCMBlock(3, 192)) { dut =>
test(new TCMBlock(3, 192, 1)) { dut =>
val _n = dut.n
val _cells = dut.size
val rand = new Random
Expand All @@ -46,20 +46,20 @@ class TCMSpec extends AnyFlatSpec with ChiselScalatestTester {
dut.io.en_wr.poke(true)
dut.clock.step()
for (i <- 0 until _n * _n) {
dut.io.r_addr(i).poke(_in_addr(i))
dut.io.r_addr(0)(i).poke(_in_addr(i))
}
for (i <- 0 until _n * _n){
dut.io.d_out(i).expect(_in_data(i))
dut.io.d_out(0)(i).expect(_in_data(i))
}
println("Result tick @ " + _i + ": ")
print_helper.printMatrix(_in_data, _n)
print_helper.printMatrixChisel(dut.io.d_out, _n)
print_helper.printMatrixChisel(dut.io.d_out(0), _n)
}
}
}

"TCM Block" should "read anytime" in {
test(new TCMBlock(2, 64)) { dut =>
test(new TCMBlock(2, 64, 1)) { dut =>
val _n = dut.n
val _cells = dut.size
val rand = new Random
Expand All @@ -81,16 +81,60 @@ class TCMSpec extends AnyFlatSpec with ChiselScalatestTester {
val _r_addr = rand.shuffle((0 until _cells).toList).take(_n * _n)
val _expected = new Array[Int](_n * _n)
for (i <- 0 until _n * _n) {
dut.io.r_addr(i).poke(_r_addr(i))
dut.io.r_addr(0)(i).poke(_r_addr(i))
}
for (i <- 0 until _n * _n) {
_expected(i) = _data(_r_addr(i))
}
println("Result tick @ " + _i + ": ")
print_helper.printMatrix(_expected, _n)
print_helper.printMatrixChisel(dut.io.d_out, _n)
print_helper.printMatrixChisel(dut.io.d_out(0), _n)
for (i <- 0 until _n * _n){
dut.io.d_out(i).expect(_data(_r_addr(i)))
dut.io.d_out(0)(i).expect(_data(_r_addr(i)))
}
}
}
}

"TCM Block" should "read anytime on different channels" in {
test(new TCMBlock(2, 64, 2)) { dut =>
val _n = dut.n
val _cells = dut.size
val _rd_ch_num = dut.rd_ch_num
val rand = new Random
val print_helper = new testUtil.PrintHelper()
val _data = new Array[Int](_cells)
for (_i <- 0 until 10) {
val _in_data = new Array[Int](_rd_ch_num * _n * _n)
val _in_addr = rand.shuffle((0 until _cells).toList).take(_rd_ch_num * _n * _n)
for (k <- 0 until _rd_ch_num){
for (i <- 0 until _n * _n) {
val _ind = k * _n * _n + i
_in_data(_ind) = rand.between(0, 255)
dut.io.d_in(i).poke(_in_data(_ind))
dut.io.w_addr(i).poke(_in_addr(_ind))
_data(_in_addr(_ind)) = _in_data(_ind)
}
dut.io.en_wr.poke(true)
dut.clock.step()
}
}
for(_i <- 0 until 10){
val _r_addr = rand.shuffle((0 until _cells).toList).take(_rd_ch_num * _n * _n)
val _expected = new Array[Int](_rd_ch_num * _n * _n)
for (k <- 0 until _rd_ch_num){
for (i <- 0 until _n * _n) {
val _ind = k * _n * _n + i
dut.io.r_addr(k)(i).poke(_r_addr(_ind))
_expected(_ind) = _data(_r_addr(_ind))
}
}
println("Result tick @ " + _i + ": ")
for (k <- 0 until _rd_ch_num){
for (i <- 0 until _n * _n){
val _ind = k * _n * _n + i
dut.io.d_out(k)(i).expect(_data(_r_addr(_ind)))
}
}
}
}
Expand Down

0 comments on commit 9b12a92

Please sign in to comment.