官术网_书友最值得收藏!

3.9 WISHBONE對RAM/ROM的支持

3.9.1 WISHBONE與RAM和ROM的互聯(lián)

遵守WISHBONE規(guī)范的IP可以與任何類型的RAM和ROM互聯(lián),只是對于不同的RAM和ROM,接口的復(fù)雜度不同,工作效率也不同。WISHBONE規(guī)范在設(shè)計(jì)時(shí)更多地考慮了對典型RAM和ROM的高效支持,而這些RAM/ROM在FPGA和ASIC片內(nèi)是普遍使用的。

WISHBONE主設(shè)備接口與RAM的連接示例如圖3-20所示。典型的同步RAM具有一個(gè)時(shí)鐘輸入,一個(gè)寫使能信號WE,地址信號以及數(shù)據(jù)輸入DIN、數(shù)據(jù)輸出信號DOUT,有時(shí)還包括片選信號CE。圖3-20中圖(a)表示RAM寫操作。在時(shí)鐘上升沿0,主設(shè)備將ADR_O()、DAT_O()置為合適的值,將WE_O置高表示寫操作;在時(shí)鐘上升沿1,DAT_O()被寫到ADR_O()對應(yīng)的RAM位置。圖3-20中圖(b)表示RAM讀操作。在時(shí)鐘上升沿0,主設(shè)備將ADR_O()置為合適的值,將WE_O置低表示讀操作;在時(shí)鐘上升沿1,DAT_O()被主設(shè)備采樣。

圖3-20 WISHBONE主設(shè)備接口與同步RAM的連接

(b)異步讀周期

(a)同步寫周期

WISHBONE主設(shè)備接口與ROM的連接和時(shí)序更加簡單,只需要地址輸入ADR()和數(shù)據(jù)輸出DOUT(),時(shí)鐘信號都不需要,如圖3-21所示。

圖3-21 WISHBONE主設(shè)備接口與ROM的連接

3.9.2 WISHBONE兼容的RAM和Flash仿真模型

在OR1200的驗(yàn)證中將使用到WISHBONE兼容的RAM和Flash模型,因此,在這里給出所使用的RAM和Flash的源代碼。

RAM的大小為2MB,是實(shí)際FPGA或ASIC RAM如idt71256sa15 SRAM的等效行為模型,其源代碼如下:

module sram_top (
  wb_clk_i, wb_rst_i,
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
  wb_stb_i, wb_ack_o, wb_err_o,
);
……
parameter       aw = 19;
……
reg    [7:0]         mem [2097151:0];//RAM為2MB,因此地址寬度aw = 19
//地址不能大于2M
assign wb_err_o = wb_cyc_i & wb_stb_i & (|wb_adr_i[23:21]);
assign adr = {8'h00, wb_adr_i[23:2], 2'b00};
//SRAM讀邏輯
assign wb_dat_o[7:0] = mem[adr+3];
assign wb_dat_o[15:8] = mem[adr+2];
assign wb_dat_o[23:16] = mem[adr+1];
assign wb_dat_o[31:24] = mem[adr+0];
//寫邏輯
always @(posedge wb_rst_i or posedge wb_clk_i)
      if (wb_cyc_i & wb_stb_i & wb_we_i) begin
            if (wb_sel_i[0])
                mem[adr+3] <= #1 wb_dat_i[7:0];
            if (wb_sel_i[1])
                mem[adr+2] <= #1 wb_dat_i[15:8];
            if (wb_sel_i[2])
                mem[adr+1] <= #1 wb_dat_i[23:16];
            if (wb_sel_i[3])
                mem[adr+0] <= #1 wb_dat_i[31:24];
      end
assign wb_ack_o = wb_cyc_i & wb_stb_i & ~wb_err_o;
endmodule

所使用的Flash實(shí)際上是一個(gè)只讀的Flash,模型仿真了典型的NorFlash如INTEL 28f016s3 FLASH的讀時(shí)序,而忽略了寫時(shí)序。主設(shè)備每讀32比特的數(shù)據(jù)需要4個(gè)時(shí)鐘周期。其源代碼如下:

module flash_top (
    wb_clk_i, wb_rst_i,
    wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
    wb_stb_i, wb_ack_o, wb_err_o
  );
  //內(nèi)部數(shù)據(jù)線和寄存器
  reg [7:0]       mem [2097151:0]; //2M字節(jié)
  wire    [31:0]      adr;
  reg         wb_err_o;
  reg [31:0]      prev_adr;
  reg [1:0]       delay;
  wire            wb_err;
  //
  assign adr = {8'h00, wb_adr_i[23:2], 2'b00};
  //Flash的初始化
  initial $readmemh("../src/flash.in", mem, 0);
  //讀模型,數(shù)據(jù)被一次賦值
  assign wb_dat_o[7:0] = wb_adr_i[23:0] < 65535 ? mem[adr+3] : 8'h00;
  assign wb_dat_o[15:8] = wb_adr_i[23:0] < 65535 ? mem[adr+2] : 8'h00;
  assign wb_dat_o[23:16] = wb_adr_i[23:0] < 65535 ? mem[adr+1] : 8'h00;
  assign wb_dat_o[31:24] = wb_adr_i[23:0] < 65535 ? mem[adr+0] : 8'h00;
    // delay邏輯,該邏輯的目的是每次發(fā)生讀操作,都在4個(gè)周期后產(chǎn)生應(yīng)答信號wb_ack_o
    always @(posedge wb_clk_i or posedge wb_rst_i)
        if (wb_rst_i) begin
            delay <= #1 2'd3;
            prev_adr <= #1 32'h0000_0000;
        end
        else if (delay && (wb_adr_i == prev_adr) && wb_cyc_i && wb_stb_i)
            delay <= #1 delay -2'd1;
        else if (wb_ack_o || wb_err_o || (wb_adr_i != prev_adr) || ~wb_stb_i) begin
            delay <= #1 2'd0;   // delay ... can range from 3 to 0
            prev_adr <= #1 wb_adr_i;
        end
    assign wb_ack_o = wb_cyc_i & wb_stb_i & ~wb_err & (delay == 2'd0) & (wb_adr_i == prev_adr);
    //總線操作錯(cuò)誤信號,錯(cuò)誤產(chǎn)生的原因是輸入地址值過大
    assign wb_err = wb_cyc_i & wb_stb_i & (delay == 2'd0) & (|wb_adr_i[23:21]);
    always @(posedge wb_clk_i or posedge wb_rst_i)
        if (wb_rst_i)
            wb_err_o <= #1 1'b0;
        else
            wb_err_o <= #1 wb_err & !wb_err_o;
    endmodule
主站蜘蛛池模板: 福清市| 宾阳县| 图木舒克市| 赣榆县| 太和县| 濉溪县| 夏津县| 齐齐哈尔市| 泰兴市| 海林市| 深泽县| 仲巴县| 永兴县| 白城市| 白山市| 襄樊市| 化德县| 陆丰市| 深水埗区| 开远市| 湾仔区| 东明县| 云林县| 永安市| 石渠县| 正镶白旗| 岳阳市| 慈利县| 福泉市| 繁峙县| 景东| 来安县| 石门县| 峨眉山市| 临猗县| 永吉县| 温州市| 临湘市| 新密市| 万安县| 南城县|