前言

他们都说这一部分不需要自己设计,还说了公司里面这部分都是买的,dft和bist前期就不用介入工作,因为买的IP里面已经集成进去了。如果公司没买IP,都是自己做的,那就需要前期和设计工程师一起交流,留下接口。

仅从设计层面来讲,sram_core.v的复杂程度也挺高的(仅针对小编小白)!所以,这部分打算直接附带码,先不做任何解释!如果后面还想分析,再附!

内部模块 sram_core.v

结合上面的图和下面的代码,理解:sram_core就是在里面例化了8片sram_bist

module sram_core(//input signalsinput                hclk,input              sram_clk,input              hresetn,input               sram_wen,        // =1 读sram; =0,写sram.8个一起读或者一起写input    [12:0]  sram_addr,input [31:0]  sram_wdata_in,   //data write into sram when "sram_wen_in" active lowinput    [3:0]     bank0_csn,       //两个bank,每个bank有四个片选input    [3:0]     bank1_csn,input               bist_en,         //BIST test modeinput            dft_en,          //DFT test mode//output signalsoutput [7:0]  sram_q0,output [7:0]    sram_q1,output [7:0]    sram_q2,output [7:0]    sram_q3,output [7:0]    sram_q4,output [7:0]    sram_q5,output [7:0]    sram_q6,output [7:0]    sram_q7,output            bist_done,  //When "bist_done" is high, it shows BIST test is over.output [7:0]  bist_fail   //"bist_fail" shows the results of each sram funtions.);//Every sram bist's work state and results output.wire bist_done0;wire bist_fail0;wire bist_done1;wire bist_fail1;wire bist_done2;wire bist_fail2;wire bist_done3;wire bist_fail3;wire bist_done4;wire bist_fail4;wire bist_done5;wire bist_fail5;wire bist_done6;wire bist_fail6;wire bist_done7;wire bist_fail7;wire bank0_bistdone;wire bank1_bistdone;wire [3:0] bank0_bistfail;wire [3:0] bank1_bistfail;//bist finishing state of bank0assign bank0_bistdone = (bist_done3 && bist_done2) && (bist_done1 && bist_done0);//bist results of bank0assign bank0_bistfail = {bist_fail3,bist_fail2,bist_fail1,bist_fail0};//bist finishing state of bank1assign bank1_bistdone = (bist_done7 && bist_done6) && (bist_done5 && bist_done4);//bist results of bank1assign bank1_bistfail = {bist_fail7,bist_fail6,bist_fail5,bist_fail4};//--------------------------------------------------------------------------//the 8 srams results of BIST test and the finishing state//--------------------------------------------------------------------------assign bist_done = bank0_bistdone && bank1_bistdone;assign bist_fail = {bank1_bistfail,bank0_bistfail} ;//-------------------------------------------------------------------------//Instance 8 srams and each provides with BIST and DFT functions. //Bank0 comprises of sram0~sram3, and bank1 comprises of sram4~sram7. //In each bank, the sram control signals broadcast to each sram, and data//written per byte into each sram in little-endian style.//-------------------------------------------------------------------------//bank0 bank1读写使能以及地址都完全相同,写入的数据也相同sram_bist u_sram_bist0(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank0_csn[0]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[7:0]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q0),.bist_done        (bist_done0),.bist_fail        (bist_fail0)  );sram_bist u_sram_bist1(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank0_csn[1]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[15:8]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q1),.bist_done        (bist_done1),.bist_fail        (bist_fail1)  );sram_bist u_sram_bist2(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank0_csn[2]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[23:16]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q2),.bist_done        (bist_done2),.bist_fail        (bist_fail2)  );sram_bist u_sram_bist3(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank0_csn[3]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[31:24]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q3),.bist_done        (bist_done3),.bist_fail        (bist_fail3)  );sram_bist u_sram_bist4(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank1_csn[0]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[7:0]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q4),.bist_done        (bist_done4),.bist_fail        (bist_fail4)  );sram_bist u_sram_bist5(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank1_csn[1]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[15:8]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q5),.bist_done        (bist_done5),.bist_fail        (bist_fail5)  );sram_bist u_sram_bist6(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank1_csn[2]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[23:16]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q6),.bist_done        (bist_done6),.bist_fail        (bist_fail6)  );sram_bist u_sram_bist7(.hclk             (hclk),.sram_clk         (sram_clk),.sram_rst_n       (hresetn),.sram_csn_in      (bank1_csn[3]),.sram_wen_in      (sram_wen),.sram_addr_in     (sram_addr),.sram_wdata_in    (sram_wdata_in[31:24]),.bist_en          (bist_en),.dft_en           (dft_en),.sram_data_out    (sram_q7),.bist_done        (bist_done7),.bist_fail        (bist_fail7)  );endmodule

单纯设计这个内部模块,现在真的拿不下!这个sram_core.v下面又例化了sram_bist.v,下面继续上sram_bist.v的文件。

sram_bist.v

到这一部分,突然想起来,有人一直在群里问,你们有memory_bist吗?有人回答,在某个软件下面有自带的ip,用就行。所以这部分,也是套用即可(当然,以后套用肯定要懂得原理呀)!

module sram_bist(//input signalsinput         hclk,input         sram_clk,input         sram_rst_n,input         sram_csn_in,   //chip select enable input         sram_wen_in,   //sram write or read enable; 0:write; 1:readinput[12:0]   sram_addr_in, input[7:0 ]   sram_wdata_in,input         bist_en,       // MBIST modeinput         dft_en,        // DFT mode//output signalsoutput[7:0 ]  sram_data_out, output        bist_done,     // 1: test overoutput        bist_fail      // high: MBIST Fail);//----------------------------------------------------//Internal signals connected the sram with bist module //when "bist_en" active high.//----------------------------------------------------wire sram_csn;wire sram_wen;wire sram_oen;wire [12:0] sram_a;wire [7:0]  sram_d;wire [7:0]  data_out;//Sram output data when "dft_en" active high.wire [7:0] dft_data;reg [7:0]  dft_data_r;wire [12:0] sram_addr;wire [7:0]  sram_wdata;//clock for bist logic, when bist is not work, clock should be 0.wire bist_clk;genvar K;//block sram input when cs is diable for low power design assign sram_addr = sram_csn_in ? 0 : sram_addr_in;assign sram_wdata = sram_csn_in ? 0 : sram_wdata_in;//dft test resultassign dft_data = (sram_d ^ sram_a[7:0]) ^ {sram_csn, sram_wen, sram_oen, sram_a[12:8]}; always @(posedge hclk or negedge sram_rst_n) beginif(!sram_rst_n)dft_data_r <= 0;else if(dft_en)dft_data_r <= dft_data;end//sram data outputassign sram_data_out = dft_en ? dft_data_r : data_out;// Note: Need to take place the mux using the special library cell
/*generate for(K = 0; K < 8; K = K+1 )begin :hold//BHDBWP7T holdQ (.Z(data_out[K]));end endgenerate
*///clock for bist logic, when bist is not work, clock should be 0.// Note: Need to take place the mux using the special library cell// CKMUX2D2BWP7T U_bist_clk_mux (.I0(1'b0), .I1(hclk), .S(bist_en), .Z(bist_clk));assign bist_clk = bist_en ? hclk : 1'b0;// One sram with BIST and DFT functionRA1SH u_RA1SH(.Q      (data_out),.CLK    (sram_clk),.CEN    (sram_csn),.WEN    (sram_wen),.A      (sram_a),.D      (sram_d),.OEN    (sram_oen));mbist_8kx8 u_mbist_8kx8(.b_clk   (bist_clk),.b_rst_n (sram_rst_n),.b_te    (bist_en),//--------------------------------------------------------//All the input signals will be derectly connected to//the sram input when in normal operation; and when in//BIST TEST mode, there are some mux in BIST module//selcting all sram input signals which generated by itself://sram controll signals, sram write data, etc.//--------------------------------------------------------.addr_fun     (sram_addr),.wen_fun      (sram_wen_in),.cen_fun      (sram_csn_in),.oen_fun      (1'b0),.data_fun     (sram_wdata),.ram_read_out (sram_data_out),.data_test    (sram_d),.addr_test    (sram_a),.wen_test     (sram_wen),.cen_test     (sram_csn),.oen_test     (sram_oen),.b_done       (bist_done),.b_fail       (bist_fail));endmodule

这个sram_bist下面又例化了 RA1SH和mbist_8kx8两个模块,这是最后一层例化了。下面附这两个模块的代码!

mbist_8kx8.v

这个模块,里面的状态机啥的,都值得借鉴,如果有时间,建议抠熟!

module mbist_8kx8
#(parameter WE_WIDTH = 1,parameter ADDR_WIDTH = 13,parameter DATA_WIDTH = 8)(//input signalsinput                      b_clk,    // bist clock   input                      b_rst_n,  // bist resetninput                      b_te,     // bist enableinput [(ADDR_WIDTH-1):0]   addr_fun,input [(WE_WIDTH-1):0]     wen_fun,input                      cen_fun,input                      oen_fun,input [(DATA_WIDTH-1):0]   data_fun,input [(DATA_WIDTH-1):0]   ram_read_out,//output signalsoutput [(ADDR_WIDTH-1):0]  addr_test, // address of testoutput [(WE_WIDTH-1):0]    wen_test,  // writing control of bist test modeoutput                     cen_test,  // chip enable control of bist test modeoutput                     oen_test,  // output enable control of bist test modeoutput [(DATA_WIDTH-1):0]  data_test, // data input of bist test modeoutput                           b_done,    // output state of bist test mode// When "bist_done" is high, it shows BIST test is over.output reg                 b_fail     // output result of sram function// When "bist_fail" is high, the sram function is wrong;// else, the sram function is right.);//----------------------------------------------------//Define 27 work states of BIST block for bist test//----------------------------------------------------`define IDEL1         5'b00000`define P1_WRITE0     5'b00001`define IDEL2         5'b00010`define P2_READ0      5'b00011`define P2_COMPARE0   5'b00100`define P2_WRITE1     5'b00101`define IDEL3         5'b00110`define P3_READ1      5'b00111`define P3_COMPARE1   5'b01000`define P3_WRITE0     5'b01001`define P3_READ0      5'b01010`define P3_COMPARE0   5'b01011`define P3_WRITE1     5'b01100`define IDEL4         5'b01101`define P4_READ1      5'b01110`define P4_COMPARE1   5'b01111`define P4_WRITE0     5'b10000`define IDEL5         5'b10001`define P5_READ0      5'b10010`define P5_COMPARE0   5'b10011`define P5_WRITE1     5'b10100`define P5_READ1      5'b10101`define P5_COMPARE1   5'b10110`define P5_WRITE0     5'b10111`define IDEL6         5'b11000`define P6_READ0      5'b11001`define P6_COMPARE0   5'b11010// sram address when in bist test modereg [(ADDR_WIDTH-1):0] test_addr;// bist test end signalreg r_end;reg r_end_en;// sram address reset when in bist test mode.reg test_addr_rst;// sram read or write enable signal when in bist test modereg [(WE_WIDTH-1):0] wen_test_inner;// bist start to work in IDLEreg rf_start;// compare the data read from sram with the data written into sram // enable signalreg check_en;// bist test data source select signal// "pattern_sel == 1'b0"-----> test_pattern =  32'b0;// "pattern_sel == 1'b1"-----> test_pattern =  32'b1;reg pattern_sel;wire [(DATA_WIDTH-1):0] test_pattern;reg [4:0] cstate, nstate;// 1 -- address is goign upward; 0 -- address is going downwardreg up1_down0; // 1 -- address is stepping; 0 -- address remainsreg count_en;  //-----------------------------------------------------------------//     Combinatorial portion//-----------------------------------------------------------------assign b_done = r_end;assign test_pattern = (pattern_sel == 1'b0) ? {DATA_WIDTH{1'b0}} : {DATA_WIDTH{1'b1}};//--------------------------------------------------------------------// The output values of all the mux below will be changed based on the// sram whether in normal operation or in bist test mode. //---------------------------------------------------------------------assign data_test = (b_te == 1'b1) ? test_pattern   : data_fun;assign addr_test = (b_te == 1'b1) ? test_addr      : addr_fun;assign wen_test  = (b_te == 1'b1) ? wen_test_inner : wen_fun;assign cen_test  = (b_te == 1'b1) ? 1'b0           : cen_fun;assign oen_test  = (b_te == 1'b1) ? 1'b0           : oen_fun;//--------------------------------------------------------------------//    Sequential portion//--------------------------------------------------------------------//--------------------------------// Generate bist work end signal. //--------------------------------always @(posedge b_clk , negedge b_rst_n) beginif (b_rst_n == 1'b0) r_end<=1'b0;else if (r_end_en == 1'b1) r_end<= 1'b1;elser_end <= 1'b0;end//----------------------------------------------------//          Generate the sram test address.// "test_addr_rst " and "up1_down0" decide the mode of // variable the address(increment/decrement). //-----------------------------------------------------always @(posedge b_clk , negedge b_rst_n) beginif (b_rst_n == 1'b0) test_addr <= {ADDR_WIDTH{1'b0}};else if (b_te == 1'b1) if (test_addr_rst == 1'b1) if (up1_down0 == 1'b1)test_addr<=  {ADDR_WIDTH{1'b0}};elsetest_addr<=  {ADDR_WIDTH{1'b1}};elseif (count_en == 1'b1)if (up1_down0 == 1'b1)test_addr<=  test_addr + 1'b1;elsetest_addr<=  test_addr - 1'b1;endalways @(posedge b_clk , negedge b_rst_n)if (b_rst_n == 1'b0) b_fail<=1'b1;else begin//---------------------------------------------------------//  When in bist idle1 state, "b_fail" defualt value is "0".// --------------------------------------------------------if ((b_te == 1'b1) && (rf_start == 1'b1))b_fail<=  1'b0;//------------------------------------------------------------//  "b_fail" value is "1", when data read from sram is different// from the expected data wirtten into sram.//--------------------------------------------------------------if ((b_te == 1'b1) && (check_en == 1'b1) && !(test_pattern == ram_read_out))b_fail<=  1'b1;end//------------------------------------------------------------------------------//                    Bist test state machine//   write "0"(initial sram)                         test_address 0-->1fff//   read  "0"------> compare -------->write "1"     test_address 1fff-->0//   read  "1"------> compare -------->write "0"     test_address 0-->1fff//   write "1"------> read "1"-------->compare       test_address 1fff-->0        //   write "0"------> read "0"-------->compare       test_address 0-->1fff        //   write "1"------> read "1"-------->compare       test_address 1fff-->0        //   write "0"------> read "0"-------->compare       test_address 0-->1fff        //------------------------------------------------------------------------------always @(posedge b_clk , negedge b_rst_n) beginif (b_rst_n == 1'b0) cstate<=`IDEL1;elsecstate<= nstate;endalways @(cstate or b_te or r_end or test_addr) beginup1_down0     = 1'b1;count_en      = 1'b0;r_end_en      = 1'b0;pattern_sel   = 1'b0;test_addr_rst = 1'b0;rf_start      = 1'b0;check_en      = 1'b0;wen_test_inner = {WE_WIDTH{1'b1}};nstate        = cstate;case (cstate)`IDEL1 :begintest_addr_rst = 1'b1;if (b_te == 1'b1 && r_end == 1'b0) beginnstate   = `P1_WRITE0;rf_start = 1'b1;endend`P1_WRITE0 :   //initial sram from addr 0~1fffbegincount_en       = 1'b1;wen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b0;if (test_addr == {ADDR_WIDTH{1'b1}} ) beginnstate        = `IDEL2;test_addr_rst = 1'b1;up1_down0     = 1'b0;endend`IDEL2 :beginpattern_sel   = 1'b0;up1_down0     = 1'b0;test_addr_rst = 1'b1; nstate        = `P2_READ0;end`P2_READ0 :beginnstate = `P2_COMPARE0;end`P2_COMPARE0 :  //compare all "0" data after read from addr 0~1fffbeginpattern_sel = 1'b0;check_en    = 1'b1;nstate      = `P2_WRITE1;end`P2_WRITE1 :  //all "1" write test from addr 1fff~0beginup1_down0      = 1'b0;count_en       = 1'b1;wen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b1;if (test_addr == {ADDR_WIDTH{1'b0}}) beginnstate        = `IDEL3;test_addr_rst = 1'b1;up1_down0     = 1'b1;endelsenstate        = `P2_READ0;end`IDEL3 :beginpattern_sel   = 1'b1;test_addr_rst = 1'b1;nstate        = `P3_READ1;end`P3_READ1 :beginnstate = `P3_COMPARE1;end`P3_COMPARE1 :  //compare all "1" data after read from addr 1fff~0beginpattern_sel = 1'b1;check_en    = 1'b1;nstate      = `P3_WRITE0;end`P3_WRITE0 :beginwen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b0;nstate         = `P3_READ0;end`P3_READ0 :beginnstate = `P3_COMPARE0;end`P3_COMPARE0 :beginpattern_sel = 1'b0;check_en    = 1'b1;nstate      = `P3_WRITE1;end`P3_WRITE1 :beginwen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b1;count_en       = 1'b1;if (test_addr == {ADDR_WIDTH{1'b1}}) beginnstate        = `IDEL4;test_addr_rst = 1'b1;endelsenstate        = `P3_READ1;end`IDEL4 :   // read all data from addr 1fff~0 and compare with write data "1" every time beginpattern_sel   = 1'b1;test_addr_rst = 1'b1;nstate        = `P4_READ1;end`P4_READ1 :beginnstate = `P4_COMPARE1;end`P4_COMPARE1 :beginpattern_sel = 1'b1;check_en    = 1'b1;nstate      = `P4_WRITE0;end`P4_WRITE0 :beginwen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b0;count_en       = 1'b1;if (test_addr == {ADDR_WIDTH{1'b1}}) beginnstate        = `IDEL5;test_addr_rst = 1'b1;endelse         nstate        = `P4_READ1;end`IDEL5 :  // read all data from addr 1fff~0 and compare with write data "0" every time beginpattern_sel   = 1'b1;test_addr_rst = 1'b1;nstate        = `P5_READ0;end`P5_READ0 :beginnstate = `P5_COMPARE0;end`P5_COMPARE0 :beginpattern_sel=1'b0;check_en=1'b1;nstate = `P5_WRITE1;end`P5_WRITE1 :beginwen_test_inner = {WE_WIDTH{1'b0}};pattern_sel   = 1'b1;nstate = `P5_READ1;end`P5_READ1 :beginnstate = `P5_COMPARE1;end`P5_COMPARE1 :beginpattern_sel=1'b1;check_en=1'b1;nstate = `P5_WRITE0;end`P5_WRITE0 :beginwen_test_inner = {WE_WIDTH{1'b0}};pattern_sel    = 1'b0;count_en       = 1'b1;if (test_addr == {ADDR_WIDTH{1'b1}}) beginnstate        = `IDEL6;test_addr_rst = 1'b1;endelsenstate        = `P5_READ0;end`IDEL6 :beginpattern_sel   = 1'b0;test_addr_rst = 1'b1;nstate        = `P6_READ0;end`P6_READ0 :beginnstate        = `P6_COMPARE0;end`P6_COMPARE0 :beginpattern_sel = 1'b0;check_en    = 1'b1;count_en    = 1'b1;if (test_addr == {ADDR_WIDTH{1'b1}}) beginnstate        = `IDEL1;test_addr_rst = 1'b1;r_end_en      = 1'b1;endelsenstate = `P6_READ0;enddefault :beginnstate        = `IDEL1;test_addr_rst = 1'b1;end endcaseendendmodule

RA1SH.v

module RA1SH ( //8KQ,CLK,CEN,WEN,A,D,OEN
);parameter        BITS = 8;parameter         word_depth = 8192;parameter        addr_width = 13;parameter          wordx = {BITS{1'bx}};parameter        addrx = {addr_width{1'bx}};output [BITS-1:0] Q;input CLK;input CEN;input WEN;input [addr_width-1:0] A;input [BITS-1:0] D;input OEN;reg [BITS-1:0]     mem [word_depth-1:0];reg            NOT_CEN;reg             NOT_WEN;reg             NOT_A0;reg              NOT_A1;reg              NOT_A2;reg              NOT_A3;reg              NOT_A4;reg              NOT_A5;reg              NOT_A6;reg              NOT_A7;reg              NOT_A8;reg              NOT_A9;reg              NOT_A10;reg             NOT_A11;reg             NOT_A12;reg [addr_width-1:0]    NOT_A;reg               NOT_D0;reg              NOT_D1;reg              NOT_D2;reg              NOT_D3;reg              NOT_D4;reg              NOT_D5;reg              NOT_D6;reg              NOT_D7;reg [BITS-1:0]       NOT_D;reg               NOT_CLK_PER;reg             NOT_CLK_MINH;reg            NOT_CLK_MINL;reg            LAST_NOT_CEN;reg            LAST_NOT_WEN;reg [addr_width-1:0]       LAST_NOT_A;reg [BITS-1:0]       LAST_NOT_D;reg              LAST_NOT_CLK_PER;reg            LAST_NOT_CLK_MINH;reg               LAST_NOT_CLK_MINL;wire [BITS-1:0]   _Q;wire             _OENi;wire [addr_width-1:0]   _A;wire               _CLK;wire               _CEN;wire               _OEN;wire                    _WEN;wire [BITS-1:0]   _D;wire                    re_flag;wire                    re_data_flag;reg             LATCHED_CEN;reg                     LATCHED_WEN;reg [addr_width-1:0]    LATCHED_A;reg [BITS-1:0]    LATCHED_D;reg               CENi;reg                WENi;reg [addr_width-1:0]       Ai;reg [BITS-1:0]       Di;reg [BITS-1:0]       Qi;reg [BITS-1:0]       LAST_Qi;reg             LAST_CLK;task update_notifier_buses;beginNOT_A = {NOT_A12,NOT_A11,NOT_A10,NOT_A9,NOT_A8,NOT_A7,NOT_A6,NOT_A5,NOT_A4,NOT_A3,NOT_A2,NOT_A1,NOT_A0};NOT_D = {NOT_D7,NOT_D6,NOT_D5,NOT_D4,NOT_D3,NOT_D2,NOT_D1,NOT_D0};endendtasktask mem_cycle;begincasez({WENi,CENi})2'b10: beginread_mem(1,0);end2'b00: beginwrite_mem(Ai,Di);read_mem(0,0);end2'b?1: ;2'b1x: beginread_mem(0,1);end2'bx0: beginwrite_mem_x(Ai);read_mem(0,1);end2'b0x,2'bxx: beginwrite_mem_x(Ai);read_mem(0,1);endendcaseendendtasktask update_last_notifiers;beginLAST_NOT_A = NOT_A;LAST_NOT_D = NOT_D;LAST_NOT_WEN = NOT_WEN;LAST_NOT_CEN = NOT_CEN;LAST_NOT_CLK_PER = NOT_CLK_PER;LAST_NOT_CLK_MINH = NOT_CLK_MINH;LAST_NOT_CLK_MINL = NOT_CLK_MINL;endendtasktask latch_inputs;beginLATCHED_A = _A ;LATCHED_D = _D ;LATCHED_WEN = _WEN ;LATCHED_CEN = _CEN ;LAST_Qi = Qi;endendtasktask update_logic;beginCENi = LATCHED_CEN;WENi = LATCHED_WEN;Ai = LATCHED_A;Di = LATCHED_D;endendtasktask x_inputs;integer n;beginfor (n=0; n<addr_width; n=n+1)beginLATCHED_A[n] = (NOT_A[n]!==LAST_NOT_A[n]) ? 1'bx : LATCHED_A[n] ;endfor (n=0; n<BITS; n=n+1)beginLATCHED_D[n] = (NOT_D[n]!==LAST_NOT_D[n]) ? 1'bx : LATCHED_D[n] ;endLATCHED_WEN = (NOT_WEN!==LAST_NOT_WEN) ? 1'bx : LATCHED_WEN ;LATCHED_CEN = (NOT_CEN!==LAST_NOT_CEN) ? 1'bx : LATCHED_CEN ;endendtasktask read_mem;input r_wb;input xflag;beginif (r_wb)beginif (valid_address(Ai))beginQi=mem[Ai];endelsebeginQi=wordx;endendelsebeginif (xflag)beginQi=wordx;endelsebeginQi=Di;endendendendtasktask write_mem;input [addr_width-1:0] a;input [BITS-1:0] d;begincasez({valid_address(a)})1'b0: x_mem;1'b1: mem[a]=d;endcaseendendtasktask write_mem_x;input [addr_width-1:0] a;begincasez({valid_address(a)})1'b0: x_mem;1'b1: mem[a]=wordx;endcaseendendtasktask x_mem;integer n;beginfor (n=0; n<word_depth; n=n+1)mem[n]=wordx;endendtasktask process_violations;beginif ((NOT_CLK_PER!==LAST_NOT_CLK_PER) ||(NOT_CLK_MINH!==LAST_NOT_CLK_MINH) ||(NOT_CLK_MINL!==LAST_NOT_CLK_MINL))beginif (CENi !== 1'b1)beginx_mem;read_mem(0,1);endendelsebeginupdate_notifier_buses;x_inputs;update_logic;mem_cycle;endupdate_last_notifiers;endendtaskfunction valid_address;input [addr_width-1:0] a;beginvalid_address = (^(a) !== 1'bx);endendfunctionbufif0 (Q[0], _Q[0], _OENi);bufif0 (Q[1], _Q[1], _OENi);bufif0 (Q[2], _Q[2], _OENi);bufif0 (Q[3], _Q[3], _OENi);bufif0 (Q[4], _Q[4], _OENi);bufif0 (Q[5], _Q[5], _OENi);bufif0 (Q[6], _Q[6], _OENi);bufif0 (Q[7], _Q[7], _OENi);buf (_D[0], D[0]);buf (_D[1], D[1]);buf (_D[2], D[2]);buf (_D[3], D[3]);buf (_D[4], D[4]);buf (_D[5], D[5]);buf (_D[6], D[6]);buf (_D[7], D[7]);buf (_A[0], A[0]);buf (_A[1], A[1]);buf (_A[2], A[2]);buf (_A[3], A[3]);buf (_A[4], A[4]);buf (_A[5], A[5]);buf (_A[6], A[6]);buf (_A[7], A[7]);buf (_A[8], A[8]);buf (_A[9], A[9]);buf (_A[10], A[10]);buf (_A[11], A[11]);buf (_A[12], A[12]);buf (_CLK, CLK);buf (_WEN, WEN);buf (_OEN, OEN);buf (_CEN, CEN);assign _OENi = _OEN;assign _Q = Qi;assign re_flag = !(_CEN);assign re_data_flag = !(_CEN || _WEN);always @(NOT_A0 orNOT_A1 orNOT_A2 orNOT_A3 orNOT_A4 orNOT_A5 orNOT_A6 orNOT_A7 orNOT_A8 orNOT_A9 orNOT_A10 orNOT_A11 orNOT_A12 orNOT_D0 orNOT_D1 orNOT_D2 orNOT_D3 orNOT_D4 orNOT_D5 orNOT_D6 orNOT_D7 orNOT_WEN orNOT_CEN orNOT_CLK_PER orNOT_CLK_MINH orNOT_CLK_MINL)beginprocess_violations;endalways @( _CLK )begincasez({LAST_CLK,_CLK})2'b01: beginlatch_inputs;update_logic;mem_cycle;end2'b10,2'bx?,2'b00,2'b11: ;2'b?x: beginx_mem;read_mem(0,1);endendcaseLAST_CLK = _CLK;endspecify $setuphold(posedge CLK, CEN, 1.000, 0.500, NOT_CEN);$setuphold(posedge CLK &&& re_flag, WEN, 1.000, 0.500, NOT_WEN);$setuphold(posedge CLK &&& re_flag, A[0], 1.000, 0.500, NOT_A0);$setuphold(posedge CLK &&& re_flag, A[1], 1.000, 0.500, NOT_A1);$setuphold(posedge CLK &&& re_flag, A[2], 1.000, 0.500, NOT_A2);$setuphold(posedge CLK &&& re_flag, A[3], 1.000, 0.500, NOT_A3);$setuphold(posedge CLK &&& re_flag, A[4], 1.000, 0.500, NOT_A4);$setuphold(posedge CLK &&& re_flag, A[5], 1.000, 0.500, NOT_A5);$setuphold(posedge CLK &&& re_flag, A[6], 1.000, 0.500, NOT_A6);$setuphold(posedge CLK &&& re_flag, A[7], 1.000, 0.500, NOT_A7);$setuphold(posedge CLK &&& re_flag, A[8], 1.000, 0.500, NOT_A8);$setuphold(posedge CLK &&& re_flag, A[9], 1.000, 0.500, NOT_A9);$setuphold(posedge CLK &&& re_flag, A[10], 1.000, 0.500, NOT_A10);$setuphold(posedge CLK &&& re_flag, A[11], 1.000, 0.500, NOT_A11);$setuphold(posedge CLK &&& re_data_flag, D[0], 1.000, 0.500, NOT_D0);$setuphold(posedge CLK &&& re_data_flag, D[1], 1.000, 0.500, NOT_D1);$setuphold(posedge CLK &&& re_data_flag, D[2], 1.000, 0.500, NOT_D2);$setuphold(posedge CLK &&& re_data_flag, D[3], 1.000, 0.500, NOT_D3);$setuphold(posedge CLK &&& re_data_flag, D[4], 1.000, 0.500, NOT_D4);$setuphold(posedge CLK &&& re_data_flag, D[5], 1.000, 0.500, NOT_D5);$setuphold(posedge CLK &&& re_data_flag, D[6], 1.000, 0.500, NOT_D6);$setuphold(posedge CLK &&& re_data_flag, D[7], 1.000, 0.500, NOT_D7);$period(posedge CLK, 3.000, NOT_CLK_PER);$width(posedge CLK, 1.000, 0, NOT_CLK_MINH);$width(negedge CLK, 1.000, 0, NOT_CLK_MINL);(CLK => Q[0])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[1])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[2])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[3])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[4])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[5])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[6])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(CLK => Q[7])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);(OEN => Q[0])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[1])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[2])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[3])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[4])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[5])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[6])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);(OEN => Q[7])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);endspecify endmodule

后记

这是AHB-SRAM项目中,内部模块sram_core.v的所有文件,如果需要跳转到查看此项目的架构,请点击跳转
AHB-SRAM简单设计之架构图解

笔者是小白,自学输出过程中,难免有错误,请大家指正!

AHB-SRAM简单设计之内部模块 sram_core.v相关推荐

  1. AHB-SRAM简单设计之 顶层模块sram_top.v

    前言 这部分就是顶层模块,直接将两个子模块例化并且连接端口就行了,直接看图施工! SRAM控制单元 sram_top.v module sramc_top(//input signalsinput w ...

  2. AHB-SRAM简单设计之架构图解

    前言 还是慢慢来,比较快!在接触这个小项目时,就有种想法,吃透项目! 参考文章:基于AHB总线的sram控制器设计.AHB-SRAMC项目(结构图,核心代码.Testbench架构) 问:对于小白,该 ...

  3. 基于 AHB 总线的 SRAM 控制器设计

    基于 AHB 总线的 SRAM 控制器设计 一.基于 AHB 的 sram 设计 1.总体设计框架 2.AHB总线传输协议 ①没有等待状态的单个读写操作 ②有等待状态的单个读写操作 ③连续读写操作 二 ...

  4. Launcher3 模块的简单设计

    Launcher3 模块的简单设计 Lancher3 路劲: Z:\xxx\packages\apps\Launcher3 任务 1.AllApps背景透明化. 2.Allapps前3个图标变为Chr ...

  5. [译文]Domain Driven Design Reference(三)—— 模型驱动设计的构建模块

    本书是Eric Evans对他自己写的<领域驱动设计-软件核心复杂性应对之道>的一本字典式的参考书,可用于快速查找<领域驱动设计>中的诸多概念及其简明解释. 其它本系列其它文章 ...

  6. 基于FPGA的USB2.0数据传输(通过本文可以自己设计USB2.0模块)

    文章部分内容参考了相关论坛中的内容: 对文章中内容感兴趣或者有不懂的可以咨询QQ:2859340499 B站对应讲解本文视频链接 首先来说一下USB这个大家都知道的东西吧: USB通用串行总线,是应用 ...

  7. javascript框架设计之种子模块

    javascript框架设计之种子模块 本文给大家介绍的是司徒正美的javascript框架设计的第二章种子模块的相关内容,算是一个小小的读后感,小伙伴们可以参考下. 种子模块也叫核心模块,是框架中最 ...

  8. 【解析】在设计软件的模块结构时,()不能改进设计质量

    在设计软件的模块结构时,()不能改进设计质量: A.尽量减少高扇出结构  B.尽量减少高扇入结构 C.将具有相似功能的模块合并  D.完善模块的功能 解析: 在结构化设计中,系统由多个逻辑上相对独立的 ...

  9. 闲谈简单设计(KISS)疑惑

    忙碌了一年了项目又到了交付了,虽然项目能成功上线(因为还有维护支持的团队).但是个人从技术上看,这是一个不那么成功的项目,因为后期艰难的修复bug,添加feature.这与简单设计有什么关系呢?在某模 ...

最新文章

  1. 第五周周记(国庆第一天)
  2. C# 特性(attribute)
  3. Python计算机视觉:第六章 图像聚类
  4. java爬虫框架动态_java爬虫框架webmagic
  5. Android 优化电池使用时间——根据需要操作广播接收器
  6. 百度代码规范 -- PHP
  7. python中的get函数_python之函数用法get()
  8. unity塔防游戏怪物转向_红包版塔防游戏合集-可以赚钱领红包的塔防游戏-无广告塔防游戏红包版大全...
  9. coreboot学习3:启动流程跟踪之bootblock阶段
  10. 顶会ICML特别开设“怼日”Workshop,意见不同您尽管来
  11. java中选择结构有哪些_Java中的选择结构
  12. spring batch(批处理)
  13. 第六章jQuery选择器
  14. MATLAB数据拟合中的若干问题(待续)
  15. 程序员看过都说好的资源网站,你懂得!
  16. 小米8的usb计算机连接不上,小米手机usb已连接电脑不显示怎么办
  17. Vue安装必要插件element-ui插件及axios依赖(详细)
  18. DirectX 开启硬件加速
  19. DELPHI关于汉字转拼音的一些想法
  20. C语言初阶(18) | 数组详解

热门文章

  1. 面试后说hold什么意思_面试快结束时,如果面试官对你说这几句话,说明你被淘汰了!...
  2. Frida hook零基础教程
  3. linux两个光驱,llinux挂载多个光驱
  4. mybatis-plus中and和or的使用
  5. python calu_python自动重采样数据
  6. Oracle甲骨文(北京中关村)授权学习中心 简介
  7. 20190512 XTCPC游记
  8. 基于高通410c开发板,开发android端家庭控制中心APP(1)
  9. 计算机图形学:B样条画枫叶
  10. Jenkins使用入门笔记