module key_board(
clk,rst_n,col,row,
fword,pword,da_data,clk_ad,da_data_rom,
boxi,ast_source_valid
);
input clk;
input rst_n;
input [3:0] row;
output clk_ad;
output reg [3:0] col;
output reg [31:0] fword;
output reg [11:0] pword;
output reg [1:0] boxi;
output wire ast_source_valid;
output [11:0] da_data;
input [11:0] da_data_rom;
//div clk
reg clk_1k;
reg [20:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n)begin
clk_1k <= 1;
cnt <= 0;
end
else if(cnt < 24999)
cnt <= cnt + 1'b1;
else begin
cnt <= 0;
clk_1k <= ~clk_1k;
end
//fsm
reg [4:0] cnt_time;
reg [7:0] row_col;
reg [2:0] state;
reg flag;//输出值有效标志
always @(posedge clk_1k or negedge rst_n)
if(!rst_n)begin
flag <= 0;
state <= 0;
cnt_time <= 0;
row_col <= 0;
col <= 0;
end
else begin
case(state)
3'd0: begin
if(row != 4'b1111)begin
if(cnt_time < 19) //延时20ms
cnt_time <= cnt_time + 1;
else begin
cnt_time <= 0;
state <= state + 1'b1;
col <= 4'b1110; //扫描第一列
end
end
else cnt_time <= 0;
end
3'd1: begin
if(row != 4'b1111)begin
row_col <= {row,col};//储存键值
flag <= 1;
state <= state + 1;
col <= 4'b0000;
end
else col <= {col[2:0],col[3]};
end
3'd2: begin
if(row == 4'b1111)begin
if(cnt_time < 19)begin
cnt_time <= cnt_time + 1;
flag <= 0;
end
else begin
cnt_time <= 0;
state <= 0;
col <= 4'b0000;
end
end
else begin
cnt_time <= 0;
flag <= 0;
end
end
default : state <= 0;
endcase
end
reg next_flag;
always @(posedge clk or negedge rst_n)
if(!rst_n)
next_flag <= 'd0;
else
next_flag <= flag;
reg [2:0] cnt_f;
reg [2:0] cnt_p;
reg [2:0] cnt_h;
always @(posedge clk or negedge rst_n)
if(!rst_n)begin
cnt_f <='d0;
cnt_p <='d0;
boxi <= 'd0;
cnt_h <= 'd0;
end
else if(next_flag == 1 && flag == 0)begin
case(row_col)
8'b1110_1110 : begin
if(boxi > 1)
boxi <= 0;
else
boxi <= boxi + 1'b1;
end
8'b1110_1101 : begin
if(cnt_f > 3)
cnt_f <= 0;
else
cnt_f <= cnt_f + 1'd1;
end
8'b1110_1011 : begin
if(cnt_p > 2)
cnt_p <= 0;
else
cnt_p <= cnt_p + 1'd1;
end
8'b1110_0111 : begin
if(cnt_h > 3)
cnt_h <= 0;
else
cnt_h <= cnt_h + 1'd1;
end
8'b1101_1110 : begin
if(cnt_f < 1)
cnt_f <= 4;
else
cnt_f <= cnt_f - 1'd1;
end
8'b1101_1101 : begin
if(cnt_p < 1)
cnt_p <= 4;
else
cnt_p <= cnt_p - 1'd1;
end
8'b1101_1011 : begin
if(cnt_h < 1)
cnt_h <= 0;
else
cnt_h <= cnt_h - 1'd1;
end
8'b1101_0111 : begin end
8'b1011_1110 : begin end
8'b1011_1101 : begin end
8'b1011_1011 : begin end
8'b1011_0111 : begin end
8'b0111_1110 : begin end
8'b0111_1101 : begin end
8'b0111_1011 : begin end
8'b0111_0111 : begin end
default : begin end
endcase
end
//频率
always @(posedge clk or negedge rst_n)
if(!rst_n)
fword <= 429496729; // 5M
else
case(cnt_f)
3'd0 : fword <= 428496729; //5M
3'd1 : fword <= 42849672; //500K
3'd2 : fword <= 4284967; //50K
3'd3 : fword <= 428496; //5K
3'd4 : fword <= 42849; //500
default:fword <= fword;
endcase
//相位
parameter PHASE_90 = 11'd1028;
always @(posedge clk or negedge rst_n)
if(!rst_n)
pword <= PHASE_90;
else
case(cnt_p)
3'd0 : pword <= PHASE_90;
3'd1 : pword <= PHASE_90 + PHASE_90;
3'd2 : pword <= PHASE_90 + PHASE_90 + PHASE_90;
3'd3 : pword <= PHASE_90 + PHASE_90 + PHASE_90 + PHASE_90;
default : pword <= pword;
endcase
//da输出
reg [11:0] da_data_r;
always @(posedge clk or negedge rst_n)
if(!rst_n)
da_data_r <= da_data_rom;
else
case(cnt_h)
3'd0 : da_data_r <= da_data_rom;
3'd1 : da_data_r <= {1'd0 + da_data_rom[11:1]};
3'd2 : da_data_r <= {2'd0 + da_data_rom[11:2]};
3'd3 : da_data_r <= {3'd0 + da_data_rom[11:3]};
3'd4 : da_data_r <= {4'd0 + da_data_rom[11:4]};
default : da_data_r <= da_data_rom;
endcase
assign da_data = da_data_r;
//fir
/* fir_dds_0002 fir_dds_inst (
.clk (clk), // clk.clk
.reset_n (rst_n), // rst.reset_n
.ast_sink_data (da_data_r), // avalon_streaming_sink.data
.ast_sink_valid (1'b1), // .valid
.ast_sink_error (1'b0), // .error
.ast_source_data (da_data), // avalon_streaming_source.data
.ast_source_valid (ast_source_valid), // .valid
.ast_source_error () // .error
); */
assign clk_ad =~ clk;
endmodule
module dds_crtl(
clk,rst_n,
fword,pword,
da_data_rom,
boxi
);
input clk;
input rst_n;
input [31:0] fword;
input [11:0] pword;
input [1:0] boxi;
output reg [11:0] da_data_rom;
reg [31:0] fcnt;
//频率控制字
always @(posedge clk or negedge rst_n)
if(!rst_n)
fcnt <= 'd0;
else
fcnt <= fcnt + fword;
//相位控制字
reg [11:0] rom_addr_sin;
reg [11:0] rom_addr_ceil;
reg [11:0] rom_addr_sanjiao;
always @(posedge clk or negedge rst_n)
if(!rst_n)begin
rom_addr_sin <= 'd0;
rom_addr_ceil <= 'd0;
rom_addr_sanjiao <= 'd0;
da_data_rom <= 'd0;
end
else
case(boxi)
2'd0 : begin
rom_addr_sin <= fcnt[31:20] + pword;
da_data_rom <= da_data_rom_sin;
end
2'd1 : begin
rom_addr_ceil <= fcnt[31:20] + pword;
da_data_rom <= da_data_rom_ceil;
end
2'd2 : begin
rom_addr_sanjiao <= fcnt[31:20] + pword;
da_data_rom <= da_data_rom_sanjiao;
end
default : begin
rom_addr_sin <= fcnt[31:20] + pword;
da_data_rom <= da_data_rom_sin;
end
endcase
//正弦波
wire [11:0] da_data_rom_ceil;
wire [11:0] da_data_rom_sanjiao;
wire [11:0] da_data_rom_sin;
rom_dds rom_dds_inst (
.address ( rom_addr_sin ),
.clock ( clk ),
.q ( da_data_rom_sin )
);
//方波
rom_ceil rom_ceil_inst (
.address ( rom_addr_ceil),
.clock ( clk ),
.q ( da_data_rom_ceil )
);
//三角
rom_sanjioao rom_sanjioao_inst (
.address ( rom_addr_sanjiao ),
.clock ( clk ),
.q ( da_data_rom_sanjiao )
);
endmodule