matlab中载波器件怎么找,基于MATLAB生成ROM查找表的DDS-中频载波实现

从END CHINA把自己以前写过的一篇博客搬到这里来,以后就在这里安家写自己的博客了。

dds通过matlab 生成的载波nco的实现:

verilog代码为:

顶层模块:主要是来组合下面两个模块

module ddsshiyan1 (clk , dds_out) ;

input clk ;

output [9:0]  dds_out  ;

wire [9:0] add_out ;

add_dff u1 (.clk(clk) , .adder_dff_out(add_out)) ;

sin u2 (.clock(clk) , .address(add_out) , .q(dds_out)) ;

endmodule

/

add_dff模块:主要是产生频率字和累加频率字的结果

module add_dff (clk , adder_dff_out ) ;

input clk ;

output [9:0] adder_dff_out ;

reg rst ;

reg [4:0] count ;

reg [9:0] reg1 ;

reg [9:0] dff_out ;

parameter  adder_dff_in = 10'd8 ;

initial

begin

rst = 1'd0 ;

count = 5'd0 ;

dff_out <= 10'd0 ;

end

always @ (posedge clk)

if (!rst)

begin

count <= count + 1 ;

reg1 <= adder_dff_in ;

if (count == 5'd30)

begin

count <= 5'd0 ;

rst <= 1'b1 ;

end

end

else

begin

dff_out <= dff_out + reg1 ;

end

assign adder_dff_out = dff_out ;

endmodule

/

sin模块:主要是利用rom核来产生nco信号

rom核自动生成程序为:

`timescale 1 ps / 1 ps

// synopsys translate_on

module sin (

address,

clock,

q);

input[9:0]  address;

input  clock;

output[9:0]  q;

wire [9:0] sub_wire0;

wire [9:0] q = sub_wire0[9:0];

altsyncram

altsyncram_component (

.clock0 (clock),

.address_a (address),

.q_a (sub_wire0),

.aclr0 (1'b0),

.aclr1 (1'b0),

.address_b (1'b1),

.addressstall_a (1'b0),

.addressstall_b (1'b0),

.byteena_a (1'b1),

.byteena_b (1'b1),

.clock1 (1'b1),

.clocken0 (1'b1),

.clocken1 (1'b1),

.clocken2 (1'b1),

.clocken3 (1'b1),

.data_a ({10{1'b1}}),

.data_b (1'b1),

.eccstatus (),

.q_b (),

.rden_a (1'b1),

.rden_b (1'b1),

.wren_a (1'b0),

.wren_b (1'b0));

defparam

altsyncram_component.address_aclr_a = "NONE",

altsyncram_component.clock_enable_input_a = "BYPASS",

altsyncram_component.clock_enable_output_a = "BYPASS",

`ifdef NO_PLI

altsyncram_component.init_file = "DDSrom33.rif"

`else

altsyncram_component.init_file = "DDSrom33.hex"

`endif

,

altsyncram_component.intended_device_family = "Cyclone III",

altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",

altsyncram_component.lpm_type = "altsyncram",

altsyncram_component.numwords_a = 1024,

altsyncram_component.operation_mode = "ROM",

altsyncram_component.outdata_aclr_a = "NONE",

altsyncram_component.outdata_reg_a = "UNREGISTERED",

altsyncram_component.widthad_a = 10,

altsyncram_component.width_a = 10,

altsyncram_component.width_byteena_a = 1;

endmodule

//

matlab生成rom程序:

clc;clear;

N = 10;                     %储存单元地址线

depth=2^N;                 %存储单元;

widths=N;                    %数据宽度为8位;

index = linspace(0,pi*2,depth);

sin_value = sin(index);

sin_value = sin_value * (depth/2 -1);  %扩大正弦幅度值

sin_value = fix((sin_value)+0.5);

plot(sin_value);

number = [0:depth];

fid=fopen('DDSrom3.mif','w+');

fprintf(fid,'depth=%d;

',depth);

fprintf(fid,'width=%d;

',widths);

fprintf(fid,'address_radix=UNS;

');

fprintf(fid,'data_radix = DEC;

');

fprintf(fid,'Content Begin

');

for i = 1 : depth

fprintf(fid, '%d:%d;

', number(i),sin_value(i));

end

fprintf(fid,'end;');

fclose(fid);

刚开始做出来自己写的一点总结:

实验一DDS总结:

一个在例化中(为了好识别端口使本来要直接连的两个端口共同连一个有意义的net字符,记得要把net字符定义为wire型数据,否则很可能综合出来的在rtl图中看见他们不是相连的),一个在modelsim仿真中(modelsim对信号的初始化要求很高,否则未定义的信号直接默认为高阻态,而高阻态的反什么的还是高阻态,最后信号显示为高阻态),写出来总结一下。 还有个就是modelsim严格按照计算机补码区别正负,十进制的正负号是识别不了的,所以rom要用hex文件储存,用mif文件的符号modelsim识别不了,所以千万把matlab生成的mif文件转成hex文件

实验总结:

主要出现问题有三:

1,在例化中为了例化信号更好识别,自己加了新的端口,但未在程序的开头声明端口,但是quartus还不报错,导致综合出来的tll图模块之间没有连接起来,

最后是在前面加了wire语句给新定义的端口

2,刚开始学,不知道一开始就要在程序里面就开始为调用modelsim就注意要初始化,因为初始化不完全,导致modelsim仿真不出结果,出错

3,不知道modelsim不能识别mif文件中储存的负数,在观察波形中,mif中定义也要注意符号数和无符号数,转化为hex文件补码16进制存储后波形终于输出正常。

待解决问题:

matlab程序中:sin_value = sin_value * (depth/2 -1);  %扩大正弦幅度值 ,这个对出来的nco波形的精度有影响吧?还有存储地址的深度的关系。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值