这一部分记录我所完成的fpga项目中值得记录的部分,关于verilog的基本语法与vivado的介绍我就不说了,直接讲如何实现
ROM
ROM是只读存储器,其中存储的数据只能被读取,而不能被写入或修改。ROM通常包含计算机系统的启动程序和其他重要的系统信息。它在计算机硬件中起到了固化的作用,保证了系统的稳定性和可靠性。ROM中所存数据稳定,一旦存储数据就再也无法将之改变或者删除,断电后所存数据也不会消失。所以我们可以通过保存一段数据的各个数据点,通过rom把这段数据重新复现出来
coe文件的产生
vivado支持mif、coe等文件类型作为ROM文件的导入格式,这里我们以coe文件为例,其实哪种文件都可以的,那我们首先就要在matlab中产生目标波形的coe文件
xxx %目标波形
n=length(xxx);
N_ADC=16; %AD的数据宽度;
M_ADC=n; %rom的数据深度
fid = fopen('your_name.coe','w');
fprintf(fid,'MEMORY_INITIALIZATION_RADIX = 10;\n');
fprintf(fid,'MEMORY_INITIALIZATION_VECTOR =\n');
y=zeros(1,M_ADC);
for i=1:1:M_ADC
y(i)=round((2^(N_ADC-1)-1)*xxx(i));
if i == M_ADC
fprintf(fid,'%d;',y(i));
else
fprintf(fid,'%d,',y(i));
end
if mod(i,8)==0 && i ~= 0
fprintf(fid,'\n');
end
end
需要注意的是,这里的ad数据深度就跟adc采样位数是一个道理,如果是16,那就代表是一个16位的二进制数据,转化为十进制的范围就是0-65535,可以根据具体需要自己修改,ROM的深度就是你这个数据一共有多少个数据点,是由你先前采样时候的采样点数决定的,注意vivado中ROM和RAM是可以支持任意点数的,而FIFO是只能支持2的整数次方个点数的,在FIFO中不满点数的会被自动赋0。
首先打开vivado的工程,点击IP Catalog,然后在里面搜block memory generator,这个ip核里面集成了单双端口ROM和RAM模块供使用,
然后这里的width就是你写入coe文件的位数,就是adc的位数,depth就是你的数据点数,一定要对应,depth可以输大,否则待会导入文件之后就会标红报错,enable ports type可以改成always enable ,这样就是一直使能,让ROM一直输出,如果有需要让他停止的可以勾选这个,自己调节他的使能信号,下面的output register可以都不选,选了就会帮你自动打拍,选一个打一拍,选两个打两拍,一拍就是指一个时钟信号周期
然后导入自己的coe文件
不用改成global,直接点generate,下面的线程数直接拉到最大,速度稍微快点
然后在source界面最下面一条找到IP sources,找到刚刚生成的ip核,找到veo文件
这里面写的是这个ip核的例化原语,我们需要将原语添加到自己的模块之中才能使用这个ip核
其中第一行前面是我们给ip核起的名字,后面是我们例化这个ip核的名字,后面那个可以随便起,然后下面括号前面的内容我们不能改动,括号后面的内容我们就根据自己的时钟信号,地址,和输出数据来赋值,我们可以在原语中清楚的看到哪个是输入输出,在这里很明显就是时钟与地址是rom的输入,然后ip核就会根据你的地址把你coe文件里面的数字以你给的时钟的速度一个一个读出来。
reg [9:0]addr;
always @(posedge sys_clk)
begin
if (addr==10'd800)
addr <= 0; //复位地址清零
else
addr <= addr + 1; //地址自增
end
再在模块中加上这么一段,意思是每当时钟上升沿时将地址自增一,而当地址到了800的时候清零再从头开始这样反复,然后写好仿真文件之后我们既可以仿真看一下波形效果了
将波形添加到窗口之后我们把所需要的看的波形改成模拟信号,然后radix调整一下进制成有符号或者无符号的十进制数,这样就可以清楚的看到波形了,至于为什么我的波形长这样大家可以参考我之前的一篇文章雷达学习记录(一)线性调频信号的产生-优快云博客