- 片上系統(tǒng)設(shè)計(jì)思想與源代碼分析
- 陳曦 黃毅
- 971字
- 2018-12-27 17:52:49
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
- Mastering Selenium WebDriver
- ASP.NET Core Essentials
- 程序員面試算法寶典
- 數(shù)據(jù)結(jié)構(gòu)(Python語言描述)(第2版)
- Python高效開發(fā)實(shí)戰(zhàn):Django、Tornado、Flask、Twisted(第3版)
- Java 9模塊化開發(fā):核心原則與實(shí)踐
- 小學(xué)生C++創(chuàng)意編程(視頻教學(xué)版)
- 可解釋機(jī)器學(xué)習(xí):模型、方法與實(shí)踐
- Extending Puppet(Second Edition)
- 圖數(shù)據(jù)庫實(shí)戰(zhàn)
- 寫給程序員的Python教程
- JavaScript機(jī)器人編程指南
- Arduino可穿戴設(shè)備開發(fā)
- Simulation for Data Science with R
- Learning Bootstrap 4(Second Edition)