Vivado 多波形选择器可调节频率和选择波形
testbench文件。
·
代码如下
test文件
`timescale 1ns / 1ps
module sin_frecontrol_test(
input sys_clk, // 系统时钟 (97.65ns ≈ 10.24MHz)
input rom_clk, // ROM时钟
input rst_n, // 复位,低电平有效
input ena, // ROM使能端
output reg [7:0] rom_data, // ROM输出数据
output reg [7:0] rom_addr, // ROM地址
input [4:0] fre, // 频率控制字 (00001=1kHz, 10100=20kHz)
input [1:0] choose
);
// 内部寄存器
reg [31:0] clk_counter;
reg [31:0] clk_divider;
wire [7:0] rom_data_sin;
wire [7:0] rom_data_train;
wire [7:0] rom_data_square;
wire [7:0] rom_data_sawtooth;
// 计算时钟分频系数
always @(*) begin
// 基础计算: (1/(freq*256)) / 97.65ns
// 对于1kHz: 1/(1000*256) ≈ 3.906μs per sample → 3.906μs/97.65ns ≈ 40
// 对于20kHz: 1/(20000*256) ≈ 195.3ns per sample → 195.3ns/97.65ns ≈ 2
// 因此分频系数 = 40/fre (where fre=1 for 1kHz, fre=20 for 20kHz)
clk_divider = 40 / (fre == 0 ? 1 : fre); // 防止除以0
end
// 地址生成逻辑
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n) begin
clk_counter <= 0;
rom_addr <= 0;
end else if(ena) begin
if(clk_counter >= clk_divider - 1) begin
clk_counter <= 0;
rom_addr <= rom_addr + 1; // 自动在255回绕到0
end else begin
clk_counter <= clk_counter + 1;
end
end
end
// 实例化ROM
rom_sin rom_ip_sin (
.clka(rom_clk),
.addra(rom_addr),
.douta(rom_data_sin),
.ena(ena)
);
// 实例化ROM
rom_train rom_ip_train (
.clka(rom_clk),
.addra(rom_addr),
.douta(rom_data_train),
.ena(ena)
);
rom_square rom_ip_square (
.clka(rom_clk),
.addra(rom_addr),
.douta(rom_data_square),
.ena(ena)
);
// 实例化ROM
sawtooth rom_ip_sawtooth (
.clka(rom_clk),
.addra(rom_addr),
.douta(rom_data_sawtooth),
.ena(ena)
);
// 实例化ROM
always @(*) begin
case (choose)
2'b00: rom_data <= rom_data_sin;
2'b01: rom_data <= rom_data_train;
2'b10: rom_data <= rom_data_square;
2'b11: rom_data <= rom_data_sawtooth;
default: rom_data <= 8'b0;
endcase
end
endmodule
testbench文件
`timescale 1ns / 1ps
module tb_sin;
// Inputs
reg sys_clk;
reg rom_clk;
reg rst_n;
wire [7:0] rom_data;
wire [7:0] rom_addr;
reg ena;
reg [4:0] fre;
reg [1:0] choose;
// Instantiate the Unit Under Test (UUT)
sin_frecontrol_test uut (
.sys_clk(sys_clk),
.rom_clk(rom_clk),
.rst_n(rst_n),
.rom_data(rom_data),
.rom_addr(rom_addr),
.ena(ena),
.fre(fre),
.choose(choose)
);
integer i;
initial begin
// Initialize Inputs
sys_clk = 0;
rom_clk = 0;
rst_n = 0;
ena = 0;
fre = 5'b00001; // 初始1kHz
choose =2'b11;
#50 ena = 1;
#81 rst_n = 1;
// 使用for循环测试不同频率
end
// 系统时钟生成 (97.65ns周期,对应20kHz时每个点195.3ns)
always #48.825 sys_clk = ~sys_clk;
// ROM时钟生成 (100MHz)
always #5 rom_clk = ~rom_clk;
// 监视信号变化
initial begin
$monitor("Time = %tns, Freq = %0dkHz, Addr = %h",
$time, fre, rom_addr);
end
endmodule
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)