From 7b63b07408d6bfdcadfef99b581190688f9025ec Mon Sep 17 00:00:00 2001 From: Ruige Lee Date: Fri, 25 Apr 2025 17:00:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=B0=E5=9C=BA=E5=9F=BA=E6=9C=AC=E6=81=A2?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- src/main/scala/backBoard/shin/ShareSRAM.scala | 65 +++ src/main/scala/backBoard/shin/ShinTop.scala | 79 ++- .../scala/backBoard/shin/SlaveParser.scala | 23 +- tb/shinTest/ShinTopTb.v | 458 ++++++++++++++++++ 5 files changed, 592 insertions(+), 35 deletions(-) create mode 100644 tb/shinTest/ShinTopTb.v diff --git a/Makefile b/Makefile index 2124aa4..f59d898 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ testShin: -o ./tb/build/shinTest.iverilog \ -y ./generated/shin \ -I ./generated/shin \ - ./tb/shinTest/SlaveParserTb.v + ./tb/shinTest/ShinTopTb.v vvp -N ./tb/build/shinTest.iverilog -lxt2 vcdShin: diff --git a/src/main/scala/backBoard/shin/ShareSRAM.scala b/src/main/scala/backBoard/shin/ShareSRAM.scala index b1c91f0..8df28a8 100644 --- a/src/main/scala/backBoard/shin/ShareSRAM.scala +++ b/src/main/scala/backBoard/shin/ShareSRAM.scala @@ -83,4 +83,69 @@ class ShareSRAMDP extends BlackBox with HasBlackBoxInline { | |endmodule """.stripMargin) +} + + + + +class ShareSRAM2k extends BlackBox with HasBlackBoxInline { + + class ShareSRAM2kIO extends Bundle{ + val dataw = Input( UInt(8.W) ) + val addrw = Input(UInt(15.W)) + val enw = Input(Bool()) + + val datar = Output( UInt(8.W) ) + val addrr = Input(UInt(15.W)) + val enr = Input(Bool()) + + val clockr = Input(Bool()) + val clockw = Input(Bool()) + + } + val io: ShareSRAM2kIO = IO(new ShareSRAM2kIO) + + setInline("ShareSRAM2k.v", + """ + + | module ShareSRAM2k( + | input [7:0] dataw, + | input [10:0] addrw, + | input enw, + | + | output [7:0] datar, + | input [10:0] addrr, + | input enr, + | + | input clockr, + | input clockw + | ); + | + | reg [7:0] ram[0:2047]; + | reg [7:0] data_r_reg; + | + | always @(posedge clockw) begin + | if(enw) begin + | ram[addrw] <= #1 dataw; + | end + | end + | + | always @(posedge clockr) begin + | if(enr) begin + | data_r_reg <= #1 ram[addrr]; + | end + | end + | + | assign datar = data_r_reg; + | + | initial begin + | for ( integer i = 0; i < 2048; i = i + 1 ) begin + | ram[i] = $random; + | end + | + | data_r_reg = $random; + | end + | + | endmodule + """.stripMargin) } \ No newline at end of file diff --git a/src/main/scala/backBoard/shin/ShinTop.scala b/src/main/scala/backBoard/shin/ShinTop.scala index 34bf7af..bf5345e 100644 --- a/src/main/scala/backBoard/shin/ShinTop.scala +++ b/src/main/scala/backBoard/shin/ShinTop.scala @@ -31,16 +31,7 @@ class ShinTopIO extends Bundle{ val sram_w = Vec( 4, new SRAM2kWRIO) //QSPI val sram_r = Vec( 4, new SRAM2kRDIO) //QSPI - val sram = MixedVec( - Flipped(Vec(4, new SRAM2kIO)), - Flipped(Vec(4, new SRAM2kIO)), - Flipped(Vec(4, new SRAM2kIO)), - Flipped(Vec(4, new SRAM2kIO)), - Flipped(Vec(2, new SRAM2kIO)), - Flipped(Vec(2, new SRAM2kIO)), - Flipped(Vec(2, new SRAM2kIO)), - Flipped(Vec(2, new SRAM2kIO)), - ) + } @@ -66,6 +57,17 @@ class ShinTop extends Module{ Module( new SMUnit(depth = 2) ), ) + val sram = Seq( + for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, + for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, + ) + smUnit(0).io.sram_w := slaveParser.io.sram_w(0) smUnit(2).io.sram_w := slaveParser.io.sram_w(1) @@ -109,14 +111,39 @@ class ShinTop extends Module{ smUnit(5).io.deq := slaveParser.io.uSMdeq(2) smUnit(7).io.deq := slaveParser.io.uSMdeq(3) - smUnit(0).io.sram <> io.sram(0) - smUnit(1).io.sram <> io.sram(1) - smUnit(2).io.sram <> io.sram(2) - smUnit(3).io.sram <> io.sram(3) - smUnit(4).io.sram <> io.sram(4) - smUnit(5).io.sram <> io.sram(5) - smUnit(6).io.sram <> io.sram(6) - smUnit(7).io.sram <> io.sram(7) + + + + + for( i <- 0 until 4 ){ + for( j <- 0 until 4 ){ + sram(i)(j).io.clockr := clock.asBool + sram(i)(j).io.clockw := clock.asBool + + smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar + sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw + sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw + sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw + sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr + sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr + } + } + + for( i <- 4 until 8 ){ + for( j <- 0 until 2 ){ + sram(i)(j).io.clockr := clock.asBool + sram(i)(j).io.clockw := clock.asBool + + smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar + sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw + sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw + sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw + sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr + sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr + } + } + + slaveParser.io.downIn <> io.downIn @@ -127,14 +154,14 @@ class ShinTop extends Module{ slaveParser.io.timeStamp := io.timeStamp - slaveParser.io.trigAddr(0) := "hffff".U - slaveParser.io.trigAddr(1) := "hffff".U - slaveParser.io.trigAddr(2) := "hffff".U - slaveParser.io.trigAddr(3) := "hffff".U - slaveParser.io.trigAddr(4) := "hffff".U - slaveParser.io.trigAddr(5) := "hffff".U - slaveParser.io.trigAddr(6) := "hffff".U - slaveParser.io.trigAddr(7) := "hffff".U + slaveParser.io.trigAddr(0) := "hff".U + slaveParser.io.trigAddr(1) := "hff".U + slaveParser.io.trigAddr(2) := "hff".U + slaveParser.io.trigAddr(3) := "hff".U + slaveParser.io.trigAddr(4) := "hff".U + slaveParser.io.trigAddr(5) := "hff".U + slaveParser.io.trigAddr(6) := "hff".U + slaveParser.io.trigAddr(7) := "hff".U diff --git a/src/main/scala/backBoard/shin/SlaveParser.scala b/src/main/scala/backBoard/shin/SlaveParser.scala index 112a594..d514165 100644 --- a/src/main/scala/backBoard/shin/SlaveParser.scala +++ b/src/main/scala/backBoard/shin/SlaveParser.scala @@ -399,18 +399,19 @@ trait SlaveParserRW{ this: SlaveParserBase => val isWRSM6 = (addrw(14,11) === "b0111".U) - - when( downRecParser.io.subMsgReq.fire ){ - when( downRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ - addrw := downRecParser.io.subMsgReq.bits.address - } - } - val isWrite = (downRecParser.io.stateCurr === STATE_PAYLOAD_DATA) & ( //req fire 后 已经反相 ( ~isDownRecPing & (downSubMsgInfo(0).devIndex === localDevIndex) & ( (downSubMsgInfo(0).operator === 1.U) | (downSubMsgInfo(0).operator === 3.U) )) | ( isDownRecPing & (downSubMsgInfo(1).devIndex === localDevIndex) & ( (downSubMsgInfo(1).operator === 1.U) | (downSubMsgInfo(1).operator === 3.U) )) ) + when( downRecParser.io.subMsgReq.fire & downRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ + addrw := downRecParser.io.subMsgReq.bits.address + } .elsewhen( isWrite ){ + addrw := addrw + 1.U + } + + + io.sram_w(0).enw := isWrite & isWRSM0 @@ -458,8 +459,12 @@ trait SlaveParserRW{ this: SlaveParserBase => //读出uSM val isRead = - ((upRecParser.io.stateCurr === STATE_PAYLOAD_DATA) & (upSubMsgInfo(0).devIndex === localDevIndex) & (upSubMsgInfo(0).operator === 2.U | upSubMsgInfo(0).operator === 3.U)) | + ((upRecParser.io.stateCurr === STATE_PAYLOAD_DATA) & ( + (~isUpRecPing & upSubMsgInfo(0).devIndex === localDevIndex & (upSubMsgInfo(0).operator === 2.U | upSubMsgInfo(0).operator === 3.U)) | + ( isUpRecPing & upSubMsgInfo(1).devIndex === localDevIndex & (upSubMsgInfo(1).operator === 2.U | upSubMsgInfo(1).operator === 3.U)) + ) | ((upRecParser.io.stateNext === STATE_PAYLOAD_DATA) & (upRecParser.io.subMsgReq.bits.devIndex === localDevIndex) & (upRecParser.io.subMsgReq.bits.operator === 2.U | upRecParser.io.subMsgReq.bits.operator === 3.U)) + ) val addrr = Reg(UInt(15.W)) val readSMAddr = Mux1H(Seq( @@ -475,6 +480,8 @@ trait SlaveParserRW{ this: SlaveParserBase => when( upRecParser.io.subMsgReq.fire & upRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ addrr := upRecParser.io.subMsgReq.bits.address + } .elsewhen( isRead ){ + addrr := addrr + 1.U } val upStreamData = Mux1H(Seq( diff --git a/tb/shinTest/ShinTopTb.v b/tb/shinTest/ShinTopTb.v new file mode 100644 index 0000000..c57fe89 --- /dev/null +++ b/tb/shinTest/ShinTopTb.v @@ -0,0 +1,458 @@ +`timescale 1 ns / 1 ps + + +module ShinTopTb( + +); + + reg clock; + reg reset; + + + +wire io_downIn_ready; +reg io_downIn_valid = 0; +reg [7:0] io_downIn_bits_tdata = 0; +reg io_downIn_bits_tlast = 0; +reg io_downIn_bits_tuser = 0; + +reg io_downOut_ready = 1; +wire io_downOut_valid; +wire [7:0] io_downOut_bits_tdata; +wire io_downOut_bits_tlast; +wire io_downOut_bits_tuser; + +wire io_upIn_ready; +reg io_upIn_valid = 0; +reg [7:0] io_upIn_bits_tdata = 0; +reg io_upIn_bits_tlast = 0; +reg io_upIn_bits_tuser = 0; + +reg io_upOut_ready = 1; +wire io_upOut_valid; +wire [7:0] io_upOut_bits_tdata; +wire io_upOut_bits_tlast; +wire io_upOut_bits_tuser; + + + +reg [63:0] timeStamp = 0; + + + + +ShinTop s_ShinTop( + .clock(clock), + .reset(reset), + + .io_downIn_ready(io_downIn_ready), + .io_downIn_valid(io_downIn_valid), + .io_downIn_bits_tdata(io_downIn_bits_tdata), + .io_downIn_bits_tlast(io_downIn_bits_tlast), + .io_downIn_bits_tuser(io_downIn_bits_tuser), + .io_downOut_ready(io_downOut_ready), + .io_downOut_valid(io_downOut_valid), + .io_downOut_bits_tdata(io_downOut_bits_tdata), + .io_downOut_bits_tlast(io_downOut_bits_tlast), + .io_downOut_bits_tuser(io_downOut_bits_tuser), + .io_upIn_ready(io_upIn_ready), + .io_upIn_valid(io_upIn_valid), + .io_upIn_bits_tdata(io_upIn_bits_tdata), + .io_upIn_bits_tlast(io_upIn_bits_tlast), + .io_upIn_bits_tuser(io_upIn_bits_tuser), + .io_upOut_ready(io_upOut_ready), + .io_upOut_valid(io_upOut_valid), + .io_upOut_bits_tdata(io_upOut_bits_tdata), + .io_upOut_bits_tlast(io_upOut_bits_tlast), + .io_upOut_bits_tuser(io_upOut_bits_tuser), + + .io_timeStamp(timeStamp), + + .io_dSMdeq_0(1'b0), + .io_dSMdeq_1(1'b0), + .io_dSMdeq_2(1'b0), + .io_dSMdeq_3(1'b0), + .io_uSMenq_0(1'b0), + .io_uSMenq_1(1'b0), + .io_uSMenq_2(1'b0), + .io_uSMenq_3(1'b0), + + .io_sram_w_0_addrw(11'd0), + .io_sram_w_0_dataw(8'h0), + .io_sram_w_0_enw(1'b0), + .io_sram_w_1_addrw(11'd0), + .io_sram_w_1_dataw(8'h0), + .io_sram_w_1_enw(1'b0), + .io_sram_w_2_addrw(11'd0), + .io_sram_w_2_dataw(8'h0), + .io_sram_w_2_enw(1'b0), + .io_sram_w_3_addrw(11'd0), + .io_sram_w_3_dataw(8'h0), + .io_sram_w_3_enw(1'b0), + .io_sram_r_0_addrr(11'd0), + .io_sram_r_0_datar(), + .io_sram_r_0_enr(1'b0), + .io_sram_r_1_addrr(11'd0), + .io_sram_r_1_datar(), + .io_sram_r_1_enr(1'b0), + .io_sram_r_2_addrr(11'd0), + .io_sram_r_2_datar(), + .io_sram_r_2_enr(1'b0), + .io_sram_r_3_addrr(11'd0), + .io_sram_r_3_datar(), + .io_sram_r_3_enr(1'b0) + +); + + + +always @(posedge clock) begin + timeStamp <= timeStamp + 64'd1; +end + + + + + + + +initial begin + clock = 0; + reset = 0; + + #100 + reset <= 1; + + #100 + reset <= 0; + +#1000000 + $display("Time Out !!!"); + $stop; +end + +initial begin + forever begin #10 clock <= ~clock; end +end + +initial +begin + $dumpfile("./tb/build/wave.vcd"); //生成的vcd文件名称 + $dumpvars(0, ShinTopTb);//tb模块名称 +end + + + + + + + + + + + + + + + + + + + + + + +reg [7:0] testDownData[0:1000]; + +initial begin + testDownData[0] = 8'hde; + testDownData[1] = 8'h0e; +end + +// reg [11:0] testDownDataCnt = 0; + + + + + + +// always @(posedge clock) begin + +// end + + +initial begin + #1000 + + s_ShinTop.slaveParser.localDevIndex = 3; //强制设备索引为3,测试子报文操作 + + //主帧头 + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h20; + + @( io_downIn_valid & io_downIn_ready) + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h00; //heeader length 512 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h00; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h00; + + + //子报文 + for( integer i = 0; i < 8; i = i + 1 ) begin + if( i != 5 ) begin + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h0; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'd56; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + + for( integer j = 0; j < 64-8; j = j+ 1 ) begin + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'ha5; //heeader length 512 + end + end else begin //第5个子报文操作 + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h0; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'hC; //3号设备 类型空 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h08; //地址 //SM0 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h30; //地址 //偏置 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h30; //命令3 长度56 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'd56; //长度56 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; //工作计数 + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; //工作计数 + + for( integer j = 0; j < 64-8; j = j+ 1 ) begin + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = 8'h55; //heeader length 512 + end + end + end + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + io_downIn_bits_tlast = 0; + io_downIn_bits_tuser = 0; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + io_downIn_bits_tlast = 0; + io_downIn_bits_tuser = 0; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + io_downIn_bits_tlast = 0; + io_downIn_bits_tuser = 0; + + @(posedge clock) #3 + io_downIn_valid = 1; + io_downIn_bits_tdata = $random; + io_downIn_bits_tlast = 1; + io_downIn_bits_tuser = 0; + + @(posedge clock) #3 + io_downIn_valid = 0; + io_downIn_bits_tlast = 0; + + + + + #1000 + #1000 + #1000 + #1000 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h20; + + @( io_upIn_valid & io_upIn_ready) + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h00; //heeader length 512 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h00; //heeader frameInfo + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h00; //heeader frameInfo + + for( integer i = 0; i < 8; i = i + 1 ) begin + if( i != 5 ) begin + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h0; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'd56; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + + for( integer j = 0; j < 64-8; j = j+ 1 ) begin + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'ha5; //heeader length 512 + end + end else begin //第5个子报文操作 + // io_sram_r_datar = 8'hec; + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h0; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'hC; //3号设备 类型空 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h10; //地址SM1 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h10; //地址偏置 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h30; //命令3 长度56 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'd56; //长度56 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; //工作计数 + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; //工作计数 + + for( integer j = 0; j < 64-8; j = j+ 1 ) begin + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = 8'h55; //heeader length 512 + end + end + end + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + io_upIn_bits_tlast = 0; + io_upIn_bits_tuser = 0; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + io_upIn_bits_tlast = 0; + io_upIn_bits_tuser = 0; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + io_upIn_bits_tlast = 0; + io_upIn_bits_tuser = 0; + + @(posedge clock) #3 + io_upIn_valid = 1; + io_upIn_bits_tdata = $random; + io_upIn_bits_tlast = 1; + io_upIn_bits_tuser = 0; + + @(posedge clock) #3 + io_upIn_valid = 0; + io_upIn_bits_tlast = 0; +end + + + + +endmodule +