赞
踩
采用matlab产生mif文件,具体的代码如下:
clear; clc; width=8; depth=256; fid =fopen ('sin.mif','w'); fprintf(fid,'WIDTH=%d;\n',width); fprintf(fid,'DEPTH=%d;\n',depth); fprintf(fid,'ADDRESS_RADIX=UNS;\n'); fprintf(fid,'DATA_RADIX=UNS;\n'); fprintf(fid,'CONTENT BEGIN\n'); for i=0:depth-1 sin_data=floor((sin(2*pi*i/depth)+1)*0.5*(2^width-1)); data=sin_data; fprintf(fid,'%d : %d;\n',i,data); end fprintf(fid,'END;\n'); fclose (fid);
通过运行.m文件可以产生一个sin.mif文件用作rom的初始状态
首先创建工程
调用单个端口的ROM IPcore,位宽为8,深度为256,RTL视图如下
顶层文件如下
module dds_v3( input wire clk, input wire rst_n, output wire [7:0] wave ); wire [7:0] addr ; roml256x8 roml256x8_inst ( .address ( addr ), .clock ( clk ), .q ( wave ) ); dds_ctrl dds_ctrl_inst( .clk(clk), .rst_n(rst_n), .addr_sin(addr) ); endmodule
dss_ctrl代码如下
module dds_ctrl( input wire clk, input wire rst_n, output wire [7:0] addr_sin ); parameter P_word = 0; //xiangwei parameter FREQ = 123456; //f localparam [63:0] F_word = FREQ*(2**32)*20/(10**9); reg [31:0] cnt; assign addr_sin=cnt[31:24]+P_word; always @(posedge clk)begin if(rst_n==1'b0) cnt<=32'd0; else cnt<=cnt+F_word[31:0]; end endmodule
由于开发芯片频率为50MHz,可以知道单个周期的时间为20ns,由于选择的cnt的位宽是32位,所以存满一个周期所需要的时间为
T=2^32✖20ns
f=1/T
f=(10^9) / (2^32✖20)
假设我们一步的步长为F_word,那么
f=F_word✖(10^9) / (2^32✖20)
F_word=f ✖ (2^32) ✖ 20 / (10^9)
我们取cnt寄存器的高8位作为rom的地址,通过对地址的不断读取即可以实现dds功能
仿真代码如下
`timescale 1ns/1ps module dds_v3_tb; reg clk; reg rst_n; wire [7:0] wave; wire [7:0] wave1; defparam dds_v3_inst1.dds_ctrl_inst.FREQ=123456; defparam dds_v3_inst2.dds_ctrl_inst.FREQ=654321; dds_v3 dds_v3_inst1( .clk(clk), .rst_n(rst_n), .wave(wave) ); dds_v3 dds_v3_inst2( .clk(clk), .rst_n(rst_n), .wave(wave1) ); initial clk=1'b0; always #10 clk=~clk; initial begin rst_n=1'b0; #200; @(posedge clk) #2; rst_n=1'b1; repeat (20) begin while (wave != 255) @(posedge clk); while (wave != 0) @(posedge clk); end #2000; $stop; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。