赞
踩
ROM为只读存储器。可以从任意地址上读取数据,但是不能写入。所以ROM中的数据,就需要提前存放进去。在IP核中,可以通过.coe文件进行数据存放,文件格式可以参考Xilinx官方标准。
使用matlab生成.coe文件,数据为正弦波波形数据
% 1. 定义一个数据数组,范围从0到255 data = 0:1:255; % 2. 打开一个名为'sin_data.coe'的文件以供写入 fid = fopen('sin_data.coe','w'); % 3. 写入COE文件的头部信息,表示数据是十进制的 fprintf(fid,'memory_initialization_radix = 10;\n'); % 4. 写入COE文件的头部信息,表示接下来的数据向量 fprintf(fid,'memory_initialization_vector = \n'); % 5. 开始循环,生成1024个数据点 for i = 1:1:1024 % 6. 计算sin函数值并将其舍入到整数,然后写入文件 fprintf(fid,'%d',round(127*sin(2*pi/1024*i)+127)); % 8-9. 检查是否到达数据末尾,如果是,写入分号,否则写入逗号 if i == 1024 fprintf(fid,';'); else fprintf(fid,','); end % 14-16. 每打印1个数据点后,检查是否需要换行 if mod(i,1) == 0 fprintf(fid,'\n'); end end % 18. 关闭文件 fclose(fid);
成功生成coe文件
建立vivado工程
新建IP核,打开IP Catalog,在窗口搜索block
双击打开
选择单端口ROM,修改一下数据的位宽以及深度,位宽默认使用8bit,深度为1024。因为前面做了一个数据量为1024的.coe文件,所以这里深度改为1024。数据输出使能选择为Always Enabled。使输出使能一直有效。输出寄存器:输出会在时钟下输出,导致结果会慢一拍,在此处我们不需要这个选项,因此取消勾选。ROM复位的设置,如果有需要,可以进行勾选。此处,没有使用复位信号,在使用时可自行选择。
新建顶层文件
写入代码
module rom( input wire clk, input wire rst_n, output wire [7:0] q ); wire [9:0] addr; addr_ctrl addr_ctrl_inst( .clk (clk), .rst_n (rst_n), .addr (addr) ); blk_mem_gen_0 blk_mem_gen_0_inst ( .clka(clk), // input wire clka .addra(addr), // input wire [9 : 0] addra .douta(q) // output wire [7 : 0] douta ); endmodule
写地址控制模块:
module addr_ctrl( input wire clk, input wire rst_n, output reg [9:0] addr ); always @ (posedge clk, negedge rst_n) begin if(rst_n == 1'b0) addr <= 10'd0; else if(addr == 10'd1023) addr <= 10'd0; else addr <= addr + 1'b1; end endmodule
编写testbench代码
module rom_tb; reg clk; reg rst_n; wire [7:0] q; initial begin clk = 0; rst_n = 0; #105; rst_n = 1; #10000; $stop; end always #10 clk = ~clk; rom rom_inst( .clk (clk ), .rst_n (rst_n ), .q (q ) ); endmodule
进行仿真
选中输出q,右键选择wavaform style,然后选择analog就可以看到数字信号变成了模拟信号。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。