AHB-SRAM代碼

module ahb_slave_if(
//  input import from master to slave
    input           hclk,
    input           hresetn,
    input           hsel,
    input           hready,
    input           hwrite,
    input [31:0]    haddr,
    input [31:0]    hwdata,
    input [1:0]     htrans,
    input [2:0]     hburst,
    input [2:0]     hsize,

//  output import from slave to bus
    output          hready_resp,
    output [1:0]    resp,
    output [31:0]   hrdata,
    
// input import from sram to slave
    input [7:0]     sram_q0,
    input [7:0]     sram_q1,
    input [7:0]     sram_q2,
    input [7:0]     sram_q3,
    input [7:0]     sram_q4,
    input [7:0]     sram_q5,
    input [7:0]     sram_q6,
    input [7:0]     sram_q7,
    
// output import from slave to sram
    output          sram_w_en,
    output [12:0]   sram_addr_out,
    output [31:0]   sram_wdata,
    output [3:0]    bank1_csn,
    output [3:0]    bank0_csn
);

// internal wire var
    wire [31:0]     sram_data_out;
    wire            bank_sel;
    wire            sram_csn_en;
    wire            sram_write;
    wire            sram_read;
    wire [15:0]     sram_addr;  //64K, 8 * 8k
    
// internal reg var
    reg             hwrite_r;
    reg [1:0]       htrans_r;
    reg [2:0]       hsize_r;
    reg [31:0]      haddr_r;
    reg [3:0]       sram_csn;

// trans參數(shù)
    parameter   IDLE   = 2'b00,
                BUSY   = 2'b01,
                NONSEQ = 2'b10,
                SEQ    = 2'b11;
        
//step 1: 保證單周期讀寫
    assign hready_resp = 1;
    assign resp = 2'b00;
    
//step 2: data from sram to slave
    assign hrdata = sram_data_out;
    
//step 3: 確定sram_data_out
    assign sram_data_out = bank_sel ? {sram_q7, sram_q6, sram_q5, sram_q4} :
                                      {sram_q3, sram_q2, sram_q1, sram_q0} ;
                                      
// step 4: 確定bank_sel
    assign bank_sel = (sram_csn_en && sram_addr[15] == 1) ? 0 : 1;
        
    
// step 5: 確定sram_csn_en
    assign sram_csn_en = (sram_write || sram_read);
    
// step 6: 確定sram_read 和 sram_write
    assign sram_read  = ((htrans_r == SEQ || htrans_r == NONSEQ) && !hwrite_r);
    assign sram_write = ((htrans_r == SEQ || htrans_r == NONSEQ) &&  hwrite_r);
    assign sram_w_en = !sram_write;
    
// step 7:確定片選的哪些sram
    assign bank0_csn = (sram_csn_en && sram_addr[15] == 0) ? sram_csn : 4'b1111;
    assign bank1_csn = (sram_csn_en && sram_addr[15] == 1) ? sram_csn : 4'b1111;
    
// step 8: 確定sram_addr
    assign sram_addr = haddr_r[15:0];
    assign sram_addr_out = sram_addr[14:2]; //一個(gè) word 32bit
    
// step 9: 確定sram_csn,用到兩個(gè)新變量 hsize_sel haddr_sel 
    wire [1:0]      hsize_sel;
    wire [1:0]      haddr_sel;
    
    assign hsize_sel = hsize_r[1:0];
    assign haddr_sel = sram_addr[1:0];
    
    always @ (hsize_sel or haddr_sel) begin
        if(hsize_sel == 2'b10) //word 
            sram_csn = 4'b0000;
        else if(hsize_sel == 2'b01) begin //halfword
            if(haddr_sel[1] == 0)
                sram_csn = 4'b1100;
            else
                sram_csn = 4'b0011;
        end
        else if(hsize_sel == 2'b00) begin //byte
            case(haddr_sel) 
                2'b00 : sram_csn = 4'b1110;
                2'b01 : sram_csn = 4'b1101;
                2'b10 : sram_csn = 4'b1011;
                2'b11 : sram_csn = 4'b0111;
                default : sram_csn = 4'b1111;
            endcase
        end
    end
    
//step 10:打拍延時(shí)
    always @ (posedge hclk or negedge hresetn) begin
        if(!resetn) begin
            haddr_r  <= 0;
            hsize_r  <= 0;
            htrans_r <= 0;
            hwrite_r <= 0;
        end
        else if(hsel && hready)begin
            haddr_r  <= haddr;
            hsize_r  <= hsize;
            htrans_r <= htrans;
            hwrite_r <= hwrite;         
        end
        else begin
            haddr_r  <= 0;
            hsize_r  <= 0;
            htrans_r <= 0;
            hwrite_r <= 0;      
        end
    end
    
//step 11:data from slave to sram
    assign sram_wdata = hwdata;
endmodule

top文件

module sramc_top(
  //input signals
  input wire            hclk,
  input wire            sram_clk,
  input wire            hresetn,
  input wire            hsel,
  input wire            hwrite,
  input wire            hready,
  input wire [2:0]      hsize ,    
  input wire [2:0]      hburst,
  input wire [1:0]      htrans,
  input wire [31:0]     hwdata,
  input wire [31:0]     haddr,      
  //Signals for BIST and DFT test mode
  //When signal"dft_en" or "bist_en" is high, sram controller enters into test mode.        
  input wire            dft_en,
  input wire            bist_en,
  
  //output signals
  output wire           hready_resp,
  output wire [1:0]     hresp,
  output wire [31:0]    hrdata,
  //When "bist_done" is high, it shows BIST test is over.
  output wire           bist_done,
  //"bist_fail" shows the results of each sram funtions.There are 8 srams in this controller.
  output wire [7:0]     bist_fail
  );

  //Select one of the two sram blocks according to the value of sram_csn
  wire [3:0] bank0_csn;
  wire [3:0] bank1_csn;
 
  //Sram read or write signals: When it is high, read sram; low, writesram.
  wire  sram_w_en;

  //Each of 8 srams is 8kx8, the depth is 2^13, so the sram's address width is 13 bits. 
  wire [12:0] sram_addr;

  //AHB bus data write into srams
  wire [31:0] sram_wdata;

  //sram data output data which selected and read by AHB bus
  wire [7:0] sram_q0;
  wire [7:0] sram_q1;
  wire [7:0] sram_q2;
  wire [7:0] sram_q3;
  wire [7:0] sram_q4;
  wire [7:0] sram_q5;
  wire [7:0] sram_q6;
  wire [7:0] sram_q7;

 
  // Instance the two modules:           
  // ahb_slave_if.v and sram_core.v      

  ahb_slave_if  ahb_slave_if_u(
    //-----------------------------------------
    // AHB input signals into sram controller
    //-----------------------------------------
    .hclk     (hclk),
    .hresetn  (hresetn),
    .hsel     (hsel),
    .hwrite   (hwrite),
    .hready   (hready),
    .hsize    (hsize),
    .htrans   (htrans),
    .hburst   (hburst),
    .hwdata   (hwdata),
    .haddr    (haddr),
    
    //-----------------------------------------
    //8 sram blcoks data output into ahb slave
    //interface
    //-----------------------------------------
    .sram_q0   (sram_q0),
    .sram_q1   (sram_q1),
    .sram_q2   (sram_q2),
    .sram_q3   (sram_q3),
    .sram_q4   (sram_q4),
    .sram_q5   (sram_q5),
    .sram_q6   (sram_q6),
    .sram_q7   (sram_q7),

    //---------------------------------------------
    //AHB slave(sram controller) output signals 
    //---------------------------------------------
    .hready_resp  (hready_resp),
    .hresp        (hresp),
    .hrdata       (hrdata),

    //---------------------------------------------
    //sram control signals and sram address  
    //---------------------------------------------
    .sram_w_en    (sram_w_en),
    .sram_addr_out(sram_addr),
     //data write into sram
    .sram_wdata   (sram_wdata),
    //choose the corresponding sram in a bank, active low
    .bank0_csn    (bank0_csn),
    .bank1_csn    (bank1_csn)
    );

  
  sram_core  sram_core_u(
    //AHB bus signals
    .hclk        (hclk    ),
    .sram_clk    (sram_clk),
    .hresetn     (hresetn ),

    //-------------------------------------------
    //sram control singals from ahb_slave_if.v
    //-------------------------------------------
    .sram_addr    (sram_addr ),
    .sram_wdata_in(sram_wdata),
    .sram_wen     (sram_w_en ),
    .bank0_csn    (bank0_csn ),
    .bank1_csn    (bank1_csn ),
     
    //test mode enable signals
    .bist_en      (bist_en   ),
    .dft_en       (dft_en    ),

    //-------------------------------------------
    //8 srams data output into AHB bus
    //-------------------------------------------
    .sram_q0    (sram_q0),
    .sram_q1    (sram_q1),
    .sram_q2    (sram_q2),
    .sram_q3    (sram_q3),
    .sram_q4    (sram_q4),
    .sram_q5    (sram_q5),
    .sram_q6    (sram_q6),
    .sram_q7    (sram_q7),

    //test results output when in test mode
    .bist_done  (bist_done),
    .bist_fail  (bist_fail)
    );
  
endmodule

tb文件

module sramc_tb;
    reg hclk;
    reg sram_clk;
    reg hresetn;
    reg hsel;
    reg hwrite;
    reg hready;
    reg [2:0] hsize;
    reg [2:0] hburst;
    reg [1:0] htrans;
    reg [31:0] hwdata;
    reg [31:0] haddr;

    reg dft_en;
    reg bist_en;

    wire hready_resp;
    wire [1:0] hresp;
    wire [31:0] hrdata;
    wire bist_done;
    wire [7:0] bist_fail;
    reg [31:0] rdata;

    sramc_top u_top(
        .hclk            (hclk),
        .sram_clk        (sram_clk),
        .hresetn         (hresetn),
        .hsel            (hsel),
        .hwrite          (hwrite),
        .hready          (hready),
        .hsize           (hsize),
        .hburst          (hburst),   
        .htrans          (htrans),
        .hwdata          (hwdata),
        .haddr           (haddr),
        .dft_en          (dft_en),
        .bist_en         (bist_en),
        .hready_resp     (hready_resp),
        .hresp           (hresp),
        .hrdata          (hrdata),
        .bist_done       (bist_done),
        .bist_fail       (bist_fail)

    );
    //HCLK 50M
    parameter period=20;
initial begin
    hclk = 0;
    forever begin
        //#10 hclk = ~hclk;
        #10 hclk = ~hclk;
                end
        end
//不推薦 always
initial begin
    sram_clk = 0;
    forever begin
        #10 sram_clk = ~sram_clk;
    end
    end

initial begin 
    $vcdpluson();  //vcs dump waveform
    end

    parameter IDLE = 2'b00,
              BUSY = 2'b10,
              NONSEQ = 2'b10,
              SEQ = 2'b11;

initial begin
    //  ...x-delay
    hresetn = 0;
    dft_en = 0;
    bist_en = 0;//work in model mode
    htrans = IDLE;
    hsize = 2'b00;
    hwrite = 0;
    hsel = 0;
    hready = 0;
    haddr = 0;
    #200;
    hresetn = 1;

    //write_read bank0
    #10;
    sram_write(32'h0000_0050,32'ha0b0c0d0);
    #10
    sram_read(32'h0000_0050,rdata);

    //write_read bank1
    #100;
    sram_write(32'h0000_f010,32'h0a0b0c0d);
    #10;
    sram_read(32'h0000f010,rdata);
    #1000;
    $finish;
    end
    //direct test
    task sram_write(input [31:0] addr,input [31:0] wdata);
    begin
        @(posedge hclk);
        hsize = 2'b10;
          htrans = NONSEQ;
          hwrite = 1;
        hsel = 1;
        hready = 1;
        haddr = addr;
        @(posedge hclk);
        hwdata = wdata;
        end
        endtask
        //分兩拍,符合協(xié)議要求 
    task sram_read(input [31:0] addr,output [31:0] rdata);
    begin
        @(posedge hclk);
        haddr = addr;
        hsize = 2'b10;
          htrans = NONSEQ;
          hwrite = 0;
        hsel =1;
        @(posedge hclk);
        rdata = hrdata;
        end
        endtask

endmodule 






?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容