1.软件与硬件平台
软件平台:win10+ISE14.7
硬件平台:FPGA型号 XC6SLX45
2.任务要求
调用ISE内部IP核生成ROM,初始化ROM数据。利用chipscope观察ROM读时序和从中读取的数据。
3.各模块例化
3.1 创建ROM初始化文件
Xilinx FPGA的片内ROM支持初始化数据配置。我们创建一个名为rom_init.coe的文件,注意它的后缀一定是“.coe”。
初始化文件的内容格式有一定的要求,第3行到底第34行表32*8bit大小的数据。
3.2 ROM IP的产生
在添加 ROM IP 之前先新建一个 rom_test 的工程, 以下为向工程中添加 ROM IP 的方法。
- 在Prpject里选择New Source,在“New Source Wizard”界面中选择文件类型为“IP(CORE Generator & Architecture Wizard)”。File name 栏输入 rom_ip, 文件所存放的路径无需修改。
2.在“Select IP” 页面中,找到“Memories & Storage Elements->RAMs & ROMs->Block Memory Generator” ,单击选中它,接着点击“Next” 进入下一步。
弹出“Summary”页面,点击“Finish”。
3.接下来是配置页面的选项选择。“Interface Type” 选择默认的“Native” ,然后点击“Next”
到下一个配置页面。
4.弹出的第 2 个页面中,“Memory Type” 选择“Single Port ROM” ,其他配置默认即可,
然后点击“Next” 到下一个配置页面。
5.ROM 位宽“Read Width” 输入“8”bit;ROM 深度“Depth” 输入“32” 。和我们之前初始化的数据一致,其他配置默认即可,然后点击“Next” 到下一个配置页面。
6.如图所示勾选“Memory Initiazation” 下的“Load Init File” ,然后点击“Browse” 定位到前面创建的 rom_init.coe 文件所在路径。我这里是放在了工程目录下。
7.余下 2 个页面均使用默认设置即可,点击“Generate” 生成 ROM IP。
3.3 Chipscope IP产生
1.在Prpject里选择New Source,在“New Source Wizard”界面中选择文件类型为“IP(CORE Generator & Architecture Wizard)”。File name 栏输入 chipscope_icon, 文件所存放的路径无需修改。
2."Number of Control Ports"就选择1,因为只用到ILA。直接Generate就行。
3.ICON 生成 完 成 后 , 再 双 击 IP Catalog 窗 口 的 Debug&Verification 下 的ILA(Chipscope Pro –Integrate Logic Analyzer)。
4. ILA 的配置可以根据自己的需要来选择,我们这里不强求,我们这里选择一个触发Group,选择数据的采样深度为 2048,就是一次采样 2048 个点,由于我们也不知道该采样多少个点,这个深度取大一点好,但FPGA 资源有限。选择上升沿触发。
5. 我们设置触发端口的数量为最大的 256,这是考虑到以后其它的项目也会用到Chipscope, 这样程序中基本上的信号都能观察了。设置完后再 Generate。
6. 我们所需的 Chipscope 文件都已经生成好了,我们可以在 rom_test 的目录下看到生成的文件,特别要注意下图中我用红色圈出来的文件,如果在其它的工程中我们需要使用 Chipscope 的话,只要把这四个文件拷过去就好了,不要费老大力气的再重新生成一边。
3.4 ROM测试程序编写
`timescale 1ns / 1ps
module rom_test(input clk,input rst,output [7:0] rom_data);
// Inputs
reg [4:0] rom_addr;
//产生ROM地址读取数据测试
[email protected](posedge clk or negedge rst)begin
if(!rst) rom_addr <= 10'd0;
else rom_addr <= rom_addr + 1'b1;
end
// Instantiate the Unit Under Test (UUT)
rom_ip uut (
.clka(clk),
.addra(rom_addr),
.douta(rom_data)
);
wire [35:0] CONTROL0;
wire [255:0] TRIG0;
chipscope_icon icon_debug(
.CONTROL0(CONTROL0)// inout bus [35:0]
);
chipscope_ila ila_filter_debug(
.CONTROL(CONTROL0),//INOUT BUS[35:0]
.CLK(clk),
.TRIG0(TRIG0)//IN BUS [255:0]
);
assign TRIG0[7:0] = rom_data;
assign TRIG0[12:8] = rom_addr;
endmodule
添加UCF约束文件rom_test.ucf
NET clk LOC = V10 | TNM_NET = sys_clk_pin | IOSTANDARD = "LVCMOS33";
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;
#######################################################################
##reset
########################################################################
NET "rst" LOC = N4 | IOSTANDARD = "LVCMOS33"; ##
4.编译与测试
先编译工程生成 rom_test.bit 文件,再下载 bit 文件到 FPGA。接下来我们需要打开chipscope 来观察一下从 ROM 中读出的数据是否为我们初始化文件 coe 的数据。双击Analyze Design Using ChipScope。
点击 Open cable 按钮建立 JTAG 连接。
的确是我们的板子,点击OK
如下图所示,就像我们顶层module中所写,将Data Port 中 CH0 ~CH7组合成一个组并命名为 rom_data,再把 CH8 ~CH12 组合成一个组并命名为 rom_addr。这样名字和我们程序里要观察的信号名字就一样了。
点击工具栏中黑色三角形的触发按钮开始触发 Chipscope。
在 Waveform 的窗口我们可以看到 rom_addr 在不断的从 0 累加到 1f, 随着 rom_addr的变化, rom_data 也在变化, rom_data 的数据正是我们存放在 ROM 中的 coe 文件的内部。
上图中红色的T标尺代表的触发的起始位置,它的位置不能移动;绿色的O和蓝色的X是两个可移动标尺,他们两个的绝对位置以及差值均显示在波形窗口的右下角,有时候需要测量两个关键点的差值就可以拖动这两个标尺来直接得出结果。