开始一个新的设计时,我们都希望能复用以前设计中的一些部件,一方面是可以减少一些重复性的设计工作;另外一方面,以前的部件多是经过验证了的,出问题的概率也比较小。
所谓基于模型的设计,不也是在不断复用这些单元模型嘛。
当然基于模型的设计方法,能复用远不止单元模型而已,下面展示的是,复用DDS设计实现一个FSK调制。
复用DDS设计FSK调制
将之前名称为DDS设计另存为名称为FSK的设计。(“另存为”的操作就实现了对DDS设计的复用)
在新另存FSK设计中,增加一个选择器,用待调制比特切换两个频率值。
对比FSK和DDS,可以看出,复用DDS后只需要做很小的修改就能实现FSK功能。还可以在FSK中修改定点化设置,完全不会影响到原来的DDS设计。
FSK调制
对比DDS
FSK仿真验证环境
很容易修改顶层仿真验证环境以适用FSK调制:
FSK仿真波形
生成得到RTL代码也是分分钟的事,FSK的RTL代码见本文末尾。
基于模型的设计通过“复制粘贴”的简单操作,就能非常方便地复用任意层次结构的设计,包括仿真验证环境。
复用DDS设计PSK调制
再比如PSK调制,通过复用DDS设计的方式,只需要很少的设计工作量就能实现。
PSK调制
PSK仿真验证环境
PSK仿真波形
复用DDS设计幅度调制(AM)
AM调制
AM仿真验证环境
AM仿真波形
FSK调制的RTL代码:
//-----------------------------------------------------------------------------
// FILE : rtlgen_demo_fsk.v
// AUTHOR : myName
// DATE : 2020-08-20
// ABSTRACT :
// test simu-rtl_gen
//
//=====================================================================
// Created with SIMU2RTL(v20200819)
// @ 2020-08-20 15:11:27
// Simulink System:
// tb_demo_fsk
//=====================================================================
// TESTBENCH FILE : rtlgen_demo_fsk_tb.v
// TEST STIMULUS FILE : ./test_data/*.vec
//
// @Copyright 2020 MyCorp
// All rights reserved.
//-----------------------------------------------------------------------------
module rtlgen_demo_fsk (
CLK ,
RST_N ,
FREQ0 , // <24,0,u>
FREQ1 , // <24,0,u>
S , // <1>
DOUT // <10,0,t>
);
// ports declaration
input CLK ;
input RST_N ;
input [23:0] FREQ0 ; // <24,0,u>
input [23:0] FREQ1 ; // <24,0,u>
input S ; // <1>
output [ 9:0] DOUT ; // <10,0,t>
//-----------------------------------------------------------------------------
// internal signals declaration
reg [ 9:0] Reg18_REG ; // <10,0,t>
reg [23:0] Reg4_REG ; // <24,0,u>
wire [23:0] Swt1_CMB ; // <24,0,u>
wire [24:0] Add2_CMB ; // <25,1,u>
wire [23:0] Fmt3_CMB ; // <24,0,u>
wire [ 1:0] Cst6_CMB ; // <2,0,u>
wire [ 5:0] Fmt5_CMB ; // <6,-2,u>
wire [ 8:0] Sub7_CMB ; // <9,0,t>
wire [23:0] Fsh8_CMB ; // <24,2,u>
wire [ 1:0] Fmt9_CMB ; // <2>
wire Bsl15_CMB ; // <1>
wire Bsl10_CMB ; // <1>
wire [ 8:0] Swt11_CMB ; // <9,0,t>
wire [ 5:0] Fmt12_CMB ; // <6,-2,u>
reg [ 9:0] Lut13_CMB ; // <10,0,t>
wire [10:0] Neg14_CMB ; // <11,1,t>
wire [10:0] Swt16_CMB ; // <11,1,t>
reg [ 9:0] Fmt17_CMB ; // <10,0,t>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/Switch')
// Switch #1 : <24,0,u> , <24,0,u> --> <24,0,u>
assign Swt1_CMB = (S==1'B0)? FREQ0:FREQ1;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/Adder')
// Adder #2 : <24,0,u> + <24,0,u> --> <25,1,u>
assign Add2_CMB = {1'B0,Reg4_REG}+{1'B0,Swt1_CMB};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/Format')
// Format #3 : wrap & truncate <25,1,u> to <24,0,u>
assign Fmt3_CMB = Add2_CMB[23:0];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/UnitDelay')
// Register #4 : <24,0,u>
always @(posedge CLK or negedge RST_N)
begin : proc_Reg4_REG
if(RST_N==1'B0)
Reg4_REG <= 24'H0; // <24,0,u> 0.000000
else
Reg4_REG <= Fmt3_CMB;
end
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Format2')
// Format #5 : wrap & truncate <24,0,u> to <6,-2,u>
assign Fmt5_CMB = Reg4_REG[21:16];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Const')
// Constant #6 : <2,0,u> 0.500000
assign Cst6_CMB = 2'D2;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Subtractor')
// Subtractor #7 : <2,0,u> - <6,-2,u> --> <9,0,t>
assign Sub7_CMB = {1'B0,Cst6_CMB,6'D0}-{3'D0,Fmt5_CMB};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Shifter')
// Fixed Shifter #8 : <24,0,u> << 2 --> <24,2,u>
assign Fsh8_CMB = Reg4_REG;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Format3')
// Format #9 : wrap & truncate <24,2,u> to <2>
assign Fmt9_CMB = Fsh8_CMB[23:22];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/WordSplit')
// Bits-Selection #10 : Bit start: 0, length: 1 from <2>
assign Bsl10_CMB = Fmt9_CMB[0];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Switch')
// Switch #11 : <6,-2,u> , <9,0,t> --> <9,0,t>
assign Swt11_CMB = (Bsl10_CMB==1'B0)? {3'D0,Fmt5_CMB}:Sub7_CMB;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Format4')
// Format #12 : wrap & truncate <9,0,t> to <6,-2,u>
assign Fmt12_CMB = Swt11_CMB[5:0];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/LUT')
// LUT #13 : <6,-2,u> --> <10,0,t>
always @(Fmt12_CMB)
begin : proc_Lut13_CMB
case(Fmt12_CMB)
6'D0 : Lut13_CMB = 10'D0;
6'D1 : Lut13_CMB = 10'D13;
6'D2 : Lut13_CMB = 10'D25;
6'D3 : Lut13_CMB = 10'D38;
6'D4 : Lut13_CMB = 10'D50;
6'D5 : Lut13_CMB = 10'D63;
6'D6 : Lut13_CMB = 10'D75;
6'D7 : Lut13_CMB = 10'D88;
6'D8 : Lut13_CMB = 10'D100;
6'D9 : Lut13_CMB = 10'D112;
6'D10 : Lut13_CMB = 10'D124;
6'D11 : Lut13_CMB = 10'D137;
6'D12 : Lut13_CMB = 10'D149;
6'D13 : Lut13_CMB = 10'D161;
6'D14 : Lut13_CMB = 10'D172;
6'D15 : Lut13_CMB = 10'D184;
6'D16 : Lut13_CMB = 10'D196;
6'D17 : Lut13_CMB = 10'D207;
6'D18 : Lut13_CMB = 10'D219;
6'D19 : Lut13_CMB = 10'D230;
6'D20 : Lut13_CMB = 10'D241;
6'D21 : Lut13_CMB = 10'D252;
6'D22 : Lut13_CMB = 10'D263;
6'D23 : Lut13_CMB = 10'D274;
6'D24 : Lut13_CMB = 10'D284;
6'D25 : Lut13_CMB = 10'D295;
6'D26 : Lut13_CMB = 10'D305;
6'D27 : Lut13_CMB = 10'D315;
6'D28 : Lut13_CMB = 10'D325;
6'D29 : Lut13_CMB = 10'D334;
6'D30 : Lut13_CMB = 10'D344;
6'D31 : Lut13_CMB = 10'D353;
6'D32 : Lut13_CMB = 10'D362;
6'D33 : Lut13_CMB = 10'D371;
6'D34 : Lut13_CMB = 10'D379;
6'D35 : Lut13_CMB = 10'D388;
6'D36 : Lut13_CMB = 10'D396;
6'D37 : Lut13_CMB = 10'D404;
6'D38 : Lut13_CMB = 10'D411;
6'D39 : Lut13_CMB = 10'D419;
6'D40 : Lut13_CMB = 10'D426;
6'D41 : Lut13_CMB = 10'D433;
6'D42 : Lut13_CMB = 10'D439;
6'D43 : Lut13_CMB = 10'D445;
6'D44 : Lut13_CMB = 10'D452;
6'D45 : Lut13_CMB = 10'D457;
6'D46 : Lut13_CMB = 10'D463;
6'D47 : Lut13_CMB = 10'D468;
6'D48 : Lut13_CMB = 10'D473;
6'D49 : Lut13_CMB = 10'D478;
6'D50 : Lut13_CMB = 10'D482;
6'D51 : Lut13_CMB = 10'D486;
6'D52 : Lut13_CMB = 10'D490;
6'D53 : Lut13_CMB = 10'D493;
6'D54 : Lut13_CMB = 10'D497;
6'D55 : Lut13_CMB = 10'D500;
6'D56 : Lut13_CMB = 10'D502;
6'D57 : Lut13_CMB = 10'D504;
6'D58 : Lut13_CMB = 10'D506;
6'D59 : Lut13_CMB = 10'D508;
6'D60 : Lut13_CMB = 10'D510;
6'D61 : Lut13_CMB = 10'D511;
6'D62 : Lut13_CMB = 10'D511;
// 6'D63
default : Lut13_CMB = 10'D511;
endcase
end
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Negative')
// Negative #14 : <10,0,t> --> <11,1,t>
assign Neg14_CMB = ~{Lut13_CMB[9],Lut13_CMB}+1'B1;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/WordSplit')
// Bits-Selection #15 : Bit start: 1, length: 1 from <2>
assign Bsl15_CMB = Fmt9_CMB[1];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Switch1')
// Switch #16 : <10,0,t> , <11,1,t> --> <11,1,t>
assign Swt16_CMB = (Bsl15_CMB==1'B0)? {Lut13_CMB[9],Lut13_CMB}:Neg14_CMB;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/SIN-LUT/Format1')
// Format #17 : clip & truncate <11,1,t> to <10,0,t>
always @(Swt16_CMB)
begin : proc_Fmt17_CMB
if(Swt16_CMB[9]!=Swt16_CMB[10])
Fmt17_CMB = {Swt16_CMB[10],{9{~Swt16_CMB[10]}}};
else
Fmt17_CMB = Swt16_CMB[9:0];
end
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// hilite_system('tb_demo_fsk/FSK/UnitDelay2')
// Register #18 : <10,0,t>
always @(posedge CLK or negedge RST_N)
begin : proc_Reg18_REG
if(RST_N==1'B0)
Reg18_REG <= 10'H0; // <10,0,t> 0.000000
else
Reg18_REG <= Fmt17_CMB;
end
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Output
assign DOUT = Reg18_REG; // <10,0,t> hilite_system('tb_demo_fsk/FSK/OUP')
//-----------------------------------------------------------------------------
endmodule // rtlgen_demo_fsk
//-----------------------------------------------------------------------------
// Statistics:
// Input Port(non-memory): 3
// Output Port(non-memory): 1
// Instances(non-memory): 22
// Internal Signal: 18
// Total Register: 34 bits
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Internal Comb. Signals Top 50 (Vector Excluded)
// Index NAME FXP
// # 1 Add2_CMB <25,1,u>
// # 2 Fsh8_CMB <24,2,u>
// # 3 Swt1_CMB <24,0,u>
// # 4 Fmt3_CMB <24,0,u>
// # 5 Neg14_CMB <11,1,t>
// # 6 Swt16_CMB <11,1,t>
// # 7 Lut13_CMB <10,0,t>
// # 8 Sub7_CMB <9,0,t>
// # 9 Swt11_CMB <9,0,t>
// # 10 Fmt5_CMB <6,-2,u>
// # 11 Fmt12_CMB <6,-2,u>
// # 12 Fmt9_CMB <2>
// # 13 Cst6_CMB <2,0,u>
// # 14 Bsl10_CMB <1>
// # 15 Bsl15_CMB <1>
//-----------------------------------------------------------------------------
// Internal Registers Top 50 (Vector Excluded)
// Index NAME FXP
// # 1 Reg4_REG <24,0,u>
// # 2 Reg18_REG <10,0,t>
//-----------------------------------------------------------------------------
// Multiplier Count: 0 Total bits: 0
// Multiplier Top 50 of 0
// Index NAME FXP
//-----------------------------------------------------------------------------
// Adder/Subtractor Count: 2 Total bits: 0
// Adder/Subtractor Top 50 of 2
// Index NAME FXP
// # 1 Add2_CMB <25,1,u>
// # 2 Sub7_CMB <9,0,t>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// End of the file.
//-----------------------------------------------------------------------------