module top (
input wire sys_clk ,
input wire sys_rst_n ,
input wire [3:0] key ,
output wire [7:0] dac_data
); // output wire dac_cl ,
// assign dac_clk = ~sys_clk ;
// 例化间连线
wire [3:0] wave_ctrl_w ;
key_ctrl key_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key ) ,
.wave_ctrl ( wave_ctrl_w )
);
dds_ctrl dds_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.wave_ctrl ( wave_ctrl_w) ,
.dac_data ( dac_data )
);
endmodule
module dds_ctrl(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [3:0] wave_ctrl ,
output wire [7:0] dac_data
);
parameter F_WARD = 20'd42949 ;
parameter P_WARD = 12'd1024 ;
// reg signal
reg [31:0] fre_add ; // 频率字累加
reg [11:0] rom_addr_reg ; // 相位字累加
reg [13:0] rom_addr ; // 读 rom地址
wire [13:0] rom_addr_w ;
reg [03:00] wave_ctrl_reg;
assign rom_addr_w = rom_addr ;
// [03:00] wave_ctrl_reg ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
wave_ctrl_reg <= 4'd0 ;
end else begin
wave_ctrl_reg <= wave_ctrl ;
end
end
// reg [31:0] fre_add ; // 频率字累加
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
fre_add <= 32'd0 ;
end else begin
if(fre_add == 32'hFFFF_FFFF - 1'b1 || (wave_ctrl_reg != wave_ctrl)) begin
fre_add <= 32'd0 ;
end else begin
if(|wave_ctrl_reg == 1'b1) begin
fre_add <= F_WARD + fre_add ;
end else begin
fre_add <= 32'd0 ;
end
end
end
end
// reg [11:0] rom_addr_reg ; // 相位字累加
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
rom_addr_reg <= 12'd0 ;
end else begin
if( rom_addr_reg == 12'hFFF) begin
rom_addr_reg <= 12'd0 ;
end else begin
rom_addr_reg <= P_WARD + fre_add[31:20] ; // 取fre_add 的高12位宽。
end
end
end
// reg [13:0] rom_addr ; // 读 rom地址
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
rom_addr <= 14'd0 ;
end else begin
case (wave_ctrl)
4'b1000: rom_addr <= rom_addr_reg ;
4'b0100: rom_addr <= rom_addr_reg + 12'hFFF + 1'b1;
4'b0010: rom_addr <= rom_addr_reg + 13'h1FFE + 1'b1;
4'b0001: rom_addr <= rom_addr_reg + 14'h2FFD + 1'b1;
default: rom_addr <= 14'd0 ;
endcase
end
end
rom_16384x8 rom_16384x8_inst (
.address ( rom_addr_w ),
.clock ( sys_clk ),
.q ( dac_data )
);
endmodule
module key_ctrl(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [3:0] key_in ,
output reg [3:0] wave_ctrl
);
wire [3:0] key_out ;
// 例化
key_filter
#(
.MAX_CNT_20MS ( 20'd999_999 )
)
key_filter_insert
(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_in ) ,
.key_out ( key_out )
);
// output signal
// wave_ctrl
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
wave_ctrl <= 4'd0 ;
end else begin
case (key_out)
4'b1000 : wave_ctrl <= 4'b1000 ;
4'b0100 : wave_ctrl <= 4'b0100 ;
4'b0010 : wave_ctrl <= 4'b0010 ;
4'b0001 : wave_ctrl <= 4'b0001 ;
default : wave_ctrl <= wave_ctrl ;
endcase
end
end
endmodule
module key_filter
#(
parameter MAX_CNT_20MS = 20'd999_999
)(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [3:0] key_in ,
output reg [3:0] key_out
);
// reg signal define
reg [3:0] key_r0 ;
reg [3:0] key_r1 ;
reg [3:0] key_r2 ;
reg nege ;
reg pose ;
reg [19:00] cnt_20ms ;
reg add_cnt_flag ;
reg flag_20ms ;
// key_r0 key_r1 key_r2
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_r0 <= 4'b1111 ;
key_r1 <= 4'b1111 ;
key_r2 <= 4'b1111 ;
end else begin
key_r0 <= key_in ;
key_r1 <= key_r0 ;
key_r2 <= key_r1 ;
end
end
// nege
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
nege <= 1'b0 ;
end else begin
if(| (~key_r1 & key_r2)) begin
nege <= 1'b1 ;
end else begin
nege <= 1'b0 ;
end
end
end
// pose
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
pose <= 1'b0 ;
end else begin
if(| ( key_r1 & ~key_r2)) begin
pose <= 1'b1 ;
end else begin
pose <= 1'b0 ;
end
end
end
// add_cnt_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
add_cnt_flag <= 1'b0 ;
end else begin
if(nege) begin
add_cnt_flag <= 1'b1 ;
end else begin
if(pose || cnt_20ms == MAX_CNT_20MS) begin
add_cnt_flag <= 1'b0 ;
end else begin
add_cnt_flag <= add_cnt_flag ;
end
end
end
end
// cnt_20ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_20ms <= 20'd0 ;
end else begin
if(add_cnt_flag) begin
if(cnt_20ms == MAX_CNT_20MS) begin
cnt_20ms <= 20'd0 ;
end else begin
cnt_20ms <= cnt_20ms + 20'd1 ;
end
end else begin
cnt_20ms <= 20'd0 ;
end
end
end
// falg_20ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
flag_20ms <= 1'b0 ;
end else begin
if(cnt_20ms == MAX_CNT_20MS - 1'b1) begin
flag_20ms <= 1'b1 ;
end else begin
flag_20ms <= 1'b0 ;
end
end
end
// [3:0]key_out
always @(posedge sys_clk or negedge sys_rst_n) begin
// always @(*) begin // 这样的话 会综合成 数据选择器
if(~sys_rst_n) begin
key_out <= 4'b0000 ;
end else begin
if(flag_20ms) begin
key_out <= ~key_r2 ;
end else begin
key_out <= 4'b0000 ;
end
end
end
endmodule
`timescale 1ns/1ns
module test_dds_ctrl();
reg sys_clk ;
reg sys_rst_n ;
reg [3:0] wave_ctrl ;
wire [7:0] adc_data ;
// Instantiation
dds_ctrl dds_insert_test(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.wave_ctrl ( wave_ctrl ) ,
.adc_data ( adc_data )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
wave_ctrl <= 4'b0000 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( 10 ) ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 50 ) ;
#( CYCLE * 100 ) ;
#( CYCLE * 20000 )
wave_ctrl <= 4'b1000 ;
#( CYCLE * 12'hFFF * 100 ) ;
wave_ctrl <= 4'b0100 ;
#( CYCLE * 12'hFFF * 100 ) ;
wave_ctrl <= 4'b0010 ;
#( CYCLE * 12'hFFF * 100 ) ;
wave_ctrl <= 4'b0001 ;
#( CYCLE * 12'hFFF * 100 ) ;
#( CYCLE * 50 ) ;
#( CYCLE * 100 ) ;
$stop ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule
`timescale 1ns/1ns
module test_key_ctrl();
reg sys_clk ;
reg sys_rst_n ;
reg [3:0] key_in ;
wire [3:0] wave_ctrl ;
defparam key_ctrl_insert.key_filter_insert.MAX_CNT_20MS = 200 ;
// Instantiation
key_ctrl key_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_in ) ,
.wave_ctrl ( wave_ctrl )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
key_in <= 4'b1111 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( 10 ) ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 50 ) ;
key_in <= 4'b0111 ;
#( CYCLE * 700) ;
key_in <= 4'b1111 ;
#( CYCLE * 700 ) ;
#( CYCLE * 100 ) ;
key_in <= 4'b1011 ;
#( CYCLE * 700 ) ;
key_in <= 4'b1111 ;
#( CYCLE * 700 ) ;
#( CYCLE * 100 ) ;
key_in <= 4'b0111 ;
#( CYCLE * 700 ) ;
key_in <= 4'b1111 ;
#( CYCLE * 50 ) ;
#( CYCLE * 100 ) ;
key_in <= 4'b1101 ;
#( CYCLE * 700 ) ;
key_in <= 4'b1111 ;
#( CYCLE * 700 ) ;
#( CYCLE * 100 ) ;
key_in <= 4'b1110 ;
#( CYCLE * 700 ) ;
key_in <= 4'b1111 ;
#( CYCLE * 700 ) ;
#( CYCLE * 100 ) ;
$stop ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule
`timescale 1ns/1ns
module test_top();
reg sys_clk ;
reg sys_rst_n ;
reg [3:0] key ;
wire [7:0] dac_data ;
// Instantiation
top top_insert_test(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key ( key ) ,
.dac_data ( dac_data )
);
defparam top_insert_test.key_ctrl_insert.key_filter_insert.MAX_CNT_20MS = 100 ;
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
key <= 4'b1111 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( 10 ) ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 50 ) ;
#( CYCLE * 100 ) ;
key <= 4'b0111 ;
#( CYCLE * 10000) ;
key <= 4'b1111 ;
#( CYCLE * 10000) ;
#( CYCLE * 12'hFFF * 100 ) ;
key <= 4'b1011 ;
#( CYCLE * 10000) ;
key <= 4'b1111 ;
#( CYCLE * 10000) ;
#( CYCLE * 12'hFFF * 100 ) ;
key <= 4'b1101 ;
#( CYCLE * 10000) ;
key <= 4'b1111 ;
#( CYCLE * 10000) ;
#( CYCLE * 12'hFFF * 100 ) ;
key <= 4'b1110 ;
#( CYCLE * 10000) ;
key <= 4'b1111 ;
#( CYCLE * 10000) ;
#( CYCLE * 12'hFFF * 100 ) ;
key <= 4'b1110 ;
#( CYCLE * 10000) ;
key <= 4'b1111 ;
#( CYCLE * 10000) ;
#( CYCLE * 12'hFFF * 100 ) ;
#( CYCLE * 50 ) ;
#( CYCLE * 100 ) ;
$stop ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule