项目的功能目标:
-
实现一个可定时时钟的功能,用小脚丫FPGA核心模块的4个按键设置当前的时间,OLED显示数字钟的当前时间,精确到分钟即可,到整点的时候比如8:00,蜂鸣器报警,播放音频信号,最长可持续30秒;
-
实现温度计的功能,小脚丫通过板上的温度传感器实时测量环境温度,并同时间一起显示在OLED的屏幕上;
-
定时时钟整点报警的同时,将温度信息通过UART传递到电脑上,电脑上能够显示当前板子上的温度信息(任何显示形式都可以),要与OLED显示的温度值一致;
-
PC收到报警的温度信号以后,将一段音频文件(自己制作,持续10秒钟左右)通过UART发送给小脚丫FPGA,蜂鸣器播放收到的这段音频文件,OLED屏幕上显示的时间信息和温度信息都停住不再更新;(视频中忘记展示了)
-
音频文件播放完毕,OLED开始更新时间信息和当前的温度信息
项目设想:
每一个模块首先应当有自己的封装,然后用更加上级的模块对这些底层的封装进行调用,在代码上尽量简洁。
使用状态机的编写方法,精准的掌握各种时序,避免数据上的错误。
尽量整合重复的语句,避免资源过多的浪费。
大体架构
引脚图
资源报告
代码展示:
时钟分频,通过对clk_p和clk_n与运算得到正确的时钟信号。
module MyClkDevide(clk, rst_n, clk_out);
input clk;
input rst_n;
output clk_out;
parameter width = 1;
parameter n = 1;
reg [width-1:0] cnt_p, cnt_n;
reg clk_p, clk_n;
initial
begin
clk_p <= 0;
clk_n <= 0;
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_p = 0;
else if (cnt_p == n - 1)
cnt_p = 0;
else
cnt_p = cnt_p + 1;
if(!rst_n)
clk_p <= 0;
else if(cnt_p < n >> 1)
clk_p <= 0;
else
clk_p <= 1;
end
always @ (negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_n = 0;
else if(cnt_n == n - 1)
cnt_n = 0;
else
cnt_n = cnt_n + 1;
if(!rst_n)
clk_n <= 0;
else if(cnt_n < n >> 1)
clk_n <= 0;
else
clk_n <= 1;
end
assign clk_out = n == 1 ? clk : clk_p & clk_n;
endmodule
MyClock模块,用于记录时间。该模块为上面模块的升级封装。
module MyClock(clk, rst_n, key1, key2, mytime, time_sig);
input clk;
input rst_n;
input key1;
input key2;
output reg [15:0] mytime;
output time_sig;
MyClkDevide # (.width(24), .n(12000000)) u_clk (clk, rst_n, clk_out);
reg [11:0] cnt;
reg [7:0] second;
reg [7:0] minute;
reg [7:0] hour;
initial
begin
mytime = 0;
cnt = 0;
second = 0;
minute = 0;
hour = 0;
end
always @ (posedge clk_out or negedge rst_n)
begin
if(!rst_n)
begin
mytime = 0;
cnt = 0;
second = 0;
minute = 0;
hour = 0;
end
else
begin
if(second == 59)
begin
second = 0;
if(minute == 59)
begin
minute = 0;
if(hour == 23)
hour = 0;
else
hour = hour + 1;
end
else
minute = minute + 1;
end
else
second = second + 1;
if(!key1)
if(minute == 59)
begin
minute = 0;
if(hour == 23)
hour = 0;
else
hour = hour + 1;
end
else
minute = minute + 1;
if(!key2)
if(hour == 23)
hour = 0;
else
hour = hour + 1;
mytime[15:12] = hour / 10;
mytime[11:8] = hour % 10;
mytime[7:4] = minute / 10;
mytime[3:0] = minute % 10;
end
end
assign time_sig = !second && !minute;
endmodule
MyPWM模块,同样也是简单的封装。
module MyPWM(clk, p_cnt, out);
input clk;
input [7:0] p_cnt;
output out;
parameter width = 8;
parameter total_cnt = 100;
reg [width-1:0] cnt;
initial
cnt = 0;
always @ (posedge clk)
begin
if(cnt == total_cnt - 1)
cnt = 0;
else
cnt = cnt + 1;
end
assign out = cnt < p_cnt ? 1 : 0;
endmodule
MyUartTX模块,相对于RX比较好写,只需要对应好时序即可。
module MyUartTX(clk, data_buffer, send_sig, rst_n, txport, busy);
input clk;
input [7:0] data_buffer;
input send_sig;
input rst_n;
output reg txport;
output reg busy;
reg [3:0] cnt;
reg state_r;
initial
begin
txport = 1;
cnt = 0;
busy = 0;
state_r = 0;
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
txport = 1;
cnt = 0;
busy = 0;
state_r = 0;
end
else
begin
if(state_r != send_sig && send_sig)
busy = 1;
if(busy)
case(cnt)
0: begin txport = 0; cnt = cnt + 1; end
9: begin txport = 1; cnt = 0; busy = 0; end
default: begin txport = data_buffer[cnt-1]; cnt = cnt + 1; end
endcase
state_r = send_sig;
end
end
endmodule
接着是MyUartRX,因为需要采样的原因时钟频率比TX大。本示例是疯狂的1250次采样。
module MyUartRX(clk, rst_n, rxport, data_buffer, busy);
input clk;
input rst_n;
input rxport;
output reg [7:0] data_buffer;
output reg busy;
localparam Sampling = 2'b00;
localparam Idle = 2'b01;
localparam Read = 2'b10;
reg [1:0] state;
reg [1:0] state_r;
reg [5:0] cnt;
reg [11:0] s_cnt;
reg [11:0] sampling;
reg data;
initial
begin
state = Sampling;
state_r = Idle;
cnt = 0;
s_cnt = 0;
sampling = 0;
data = 0;
busy = 0;
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state = Sampling;
state_r = Idle;
cnt = 0;
s_cnt = 0;
sampling = 0;
data = 0;
busy = 0;
end
else
begin
case(state)
Sampling:
if(s_cnt < 1249)
begin
sampling = sampling + rxport;
s_cnt = s_cnt + 1;
end
else
begin
sampling = sampling + rxport;
state = state_r;
s_cnt = 0;
data = sampling >= 625;
sampling = 0;
end
Read:
begin
case(cnt)
8: begin state_r = Idle; cnt = 0; busy = 0; end
default: begin data_buffer[cnt] = data; state_r = Read; cnt = cnt + 1; end
endcase
state = Sampling;
end
Idle:
begin
if(data == 0)
begin
state_r = Read;
busy = 1;
end
state = Sampling;
end
endcase
end
end
endmodule
Uart之后的通讯协议都比较难,比如这个SPI(还算可以的吧)。记得上电时序,仔仔细细对着英文文档做,原版小脚丫因为有出厂程序所以对上电时序没啥要求。但是一旦抹除了出厂程序,你原来的上电时序可能会出问题。
module MyOLed(clk, rst_n, mytime, tempe, cs, dc, sdin, oledrst);
input clk;
input rst_n;
input [15:0] mytime;
input [11:0] tempe;
output reg cs;
output reg dc;
output reg sdin;
output reg oledrst;
localparam Init = 3'b000;
localparam Delay = 3'b001;
localparam Write = 3'b010;
localparam Main = 3'b011;
localparam Character = 3'b100;
localparam Clear = 3'b101;
localparam CMD = 1'b0;
localparam DATA = 1'b1;
localparam CMD_NUM = 23;
reg[39:0] mem[11:0];
reg [7:0] cmd [CMD_NUM-1:0];
reg [5:0] cmd_cnt;
reg [2:0] state;
reg [2:0] state_r;
reg [3:0] init_cnt;
reg [5:0] delay_num;
reg [5:0] delay_cnt;
reg [5:0] write_cnt;
reg [7:0] write_buffer;
reg write_mode;
reg [5:0] main_cnt;
reg [5:0] character_cnt;
reg [3:0] character_num;
reg [10:0] clear_cnt;
initial
begin
oledrst = 1;
state = Init;
cmd_cnt = 0;
init_cnt = 0;
delay_cnt = 0;
write_cnt = 0;
main_cnt = 0;
character_cnt = 0;
cs = 1;
cmd[0] = 8'h00;
cmd[1] = 8'h10;
cmd[2] = 8'hb0;
cmd[3] = 8'h81;
cmd[4] = 8'hff;
cmd[5] = 8'ha1;
cmd[6] = 8'ha6;
cmd[7] = 8'ha8;
cmd[8] = 8'h1f;
cmd[9] = 8'hc8;
cmd[10] = 8'hd3;
cmd[11] = 8'h00;
cmd[12] = 8'hd5;
cmd[13] = 8'h80;
cmd[14] = 8'hd9;
cmd[15] = 8'h1f;
cmd[16] = 8'hda;
cmd[17] = 8'h00;
cmd[18] = 8'hdb;
cmd[19] = 8'h40;
cmd[20] = 8'h8d;
cmd[21] = 8'h14;
cmd[22] = 8'haf;
mem[0] = {8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E}; // 0
mem[1] = {8'h00, 8'h42, 8'h7F, 8'h40, 8'h00}; // 1
mem[2] = {8'h42, 8'h61, 8'h51, 8'h49, 8'h46}; // 2
mem[3] = {8'h21, 8'h41, 8'h45, 8'h4B, 8'h31}; // 3
mem[4] = {8'h18, 8'h14, 8'h12, 8'h7F, 8'h10}; // 4
mem[5] = {8'h27, 8'h45, 8'h45, 8'h45, 8'h39}; // 5
mem[6] = {8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30}; // 6
mem[7] = {8'h01, 8'h71, 8'h09, 8'h05, 8'h03}; // 7
mem[8] = {8'h36, 8'h49, 8'h49, 8'h49, 8'h36}; // 8
mem[9] = {8'h06, 8'h49, 8'h49, 8'h29, 8'h1E}; // 9
mem[10] = {8'h00, 8'h60, 8'h60, 8'h00, 8'h00}; // .
mem[11] = {8'h00, 8'h36, 8'h36, 8'h00, 8'h00}; // :
end
always @ (negedge clk or negedge rst_n)
begin
if(!rst_n)
begin
oledrst = 1;
state = Init;
cmd_cnt = 0;
init_cnt = 0;
delay_cnt = 0;
write_cnt = 0;
main_cnt = 0;
character_cnt = 0;
cs = 1;
end
else
case(state)
Init:
begin
case(init_cnt)
0: begin oledrst = 0; state = Delay; delay_num = 5; state_r = Init; init_cnt = init_cnt + 1; end
1: begin oledrst = 1; state = Delay; delay_num = 5; state_r = Init; init_cnt = init_cnt + 1; end
2: begin
write_mode = CMD;
if(cmd_cnt < CMD_NUM)
begin
write_buffer = cmd[cmd_cnt];
state = Write;
state_r = Init;
if(cmd_cnt == CMD_NUM - 1)
begin
cmd_cnt = 0;
init_cnt = init_cnt + 1;
end
cmd_cnt = cmd_cnt + 1;
end
end
3: begin state = Main; init_cnt = 0; end
endcase
end
Delay:
begin
if(delay_cnt == delay_num - 1)
begin
delay_cnt = 0;
state = state_r;
end
else
delay_cnt = delay_cnt + 1;
end
Write:
begin
case(write_cnt)
0: begin cs = 0; dc = write_mode; sdin = write_buffer[7]; write_cnt = write_cnt + 1; end
8: begin cs = 1; state = state_r; write_cnt = 0; end
default: begin sdin = write_buffer[7-write_cnt]; write_cnt = write_cnt + 1; end
endcase
end
Main:
begin
case(main_cnt)
0: begin state = Write; write_mode = CMD; write_buffer = 8'h00; state_r = Main; main_cnt = main_cnt + 1; end
1: begin state = Write; write_mode = CMD; write_buffer = 8'h10; state_r = Main; main_cnt = main_cnt + 1; end
2: begin state = Write; write_mode = CMD; write_buffer = 8'hb0; state_r = Main; main_cnt = main_cnt + 1; end
3: begin state = Clear; state_r = Main; main_cnt = main_cnt + 1; end
4: begin state = Character; character_num = mytime[15:12]; main_cnt = main_cnt + 1; end
5: begin state = Character; character_num = mytime[11:8]; main_cnt = main_cnt + 1; end
6: begin state = Character; character_num = 11; main_cnt = main_cnt + 1; end
7: begin state = Character; character_num = mytime[7:4]; main_cnt = main_cnt + 1; end
8: begin state = Character; character_num = mytime[3:0]; main_cnt = main_cnt + 1; end
9: begin state = Write; write_mode = CMD; write_buffer = 8'h00; state_r = Main; main_cnt = main_cnt + 1; end
10: begin state = Write; write_mode = CMD; write_buffer = 8'h10; state_r = Main; main_cnt = main_cnt + 1; end
11: begin state = Write; write_mode = CMD; write_buffer = 8'hb1; state_r = Main; main_cnt = main_cnt + 1; end
12: begin state = Clear; state_r = Main; main_cnt = main_cnt + 1; end
13: begin state = Character; character_num = tempe[11:8]; main_cnt = main_cnt + 1; end
14: begin state = Character; character_num = tempe[7:4]; main_cnt = main_cnt + 1; end
15: begin state = Character; character_num = tempe[3:0]; main_cnt = main_cnt + 1; end
16: begin state = Main; main_cnt = 0; end
endcase
end
Character:
begin
case(character_cnt)
0:
begin
state = Write;
state_r = Character;
write_mode = DATA;
write_buffer = mem[character_num][39:32];
character_cnt = character_cnt + 1;
end
1:
begin
state = Write;
state_r = Character;
write_mode = DATA;
write_buffer = mem[character_num][31:24];
character_cnt = character_cnt + 1;
end
2:
begin
state = Write;
state_r = Character;
write_mode = DATA;
write_buffer = mem[character_num][23:16];
character_cnt = character_cnt + 1;
end
3:
begin
state = Write;
state_r = Character;
write_mode = DATA;
write_buffer = mem[character_num][15:8];
character_cnt = character_cnt + 1;
end
4:
begin
state = Write;
state_r = Character;
write_mode = DATA;
write_buffer = mem[character_num][7:0];
character_cnt = character_cnt + 1;
end
5: begin state = Main; character_cnt = 0; end
endcase
end
Clear:
begin
write_mode = DATA;
write_buffer = 8'h00;;
state = Write;
state_r = Clear;
if(clear_cnt == 128)
begin
clear_cnt = 0;
state = Main;
end
else
clear_cnt = clear_cnt + 1;
end
endcase
end
endmodule
剩下一个18B20,1-wire通讯协议简直是方便自己痛苦他人(我的主观臆断)。多说无益,可以多看看芯片的手册,按照标准严格做一定行。
module My18B20(clk, rst_n, bus, data_out_d, sig);
input clk;
input rst_n;
inout bus;
output reg [11:0] data_out_d;
output reg sig;
localparam Read = 3'b000;
localparam Write = 3'b001;
localparam Delay = 3'b010;
localparam Sampling = 3'b011;
localparam Main = 3'b100;
localparam ReadData = 3'b101;
localparam WriteCmd = 3'b110;
localparam Init = 3'b111;
localparam HIGH = 1'b1;
localparam HIZ = 1'bz;
localparam LOW = 1'b0;
reg [15:0] data_out;
reg bus_output;
reg data_buffer;
reg [7:0] cmd_buffer;
reg [2:0] state;
reg [2:0] state_r;
reg [5:0] init_cnt;
reg [25:0] delay_cnt;
reg [25:0] delay_num;
reg [5:0] sampling_cnt;
reg [5:0] sampling_num;
reg [5:0] sampling_result;
reg sampling_data;
reg [5:0] read_cnt;
reg [5:0] write_cnt;
reg [10:0] main_cnt;
reg [5:0] readdata_cnt;
reg [5:0] writecmd_cnt;
initial
begin
bus_output = HIZ;
state = Main;
init_cnt = 0;
delay_cnt = 0;
sampling_cnt = 0;
sampling_result = 0;
read_cnt = 0;
write_cnt = 0;
main_cnt = 0;
readdata_cnt = 0;
writecmd_cnt = 0;
sig = 0;
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
bus_output = HIZ;
state = Main;
init_cnt = 0;
delay_cnt = 0;
sampling_cnt = 0;
sampling_result = 0;
read_cnt = 0;
write_cnt = 0;
main_cnt = 0;
readdata_cnt = 0;
writecmd_cnt = 0;
sig = 0;
end
else
case(state)
Init:
case(init_cnt)
0: begin bus_output = LOW; state = Delay; delay_num = 500; state_r = Init; init_cnt = init_cnt + 1; end
1: begin bus_output = HIZ; state = Delay; delay_num = 500; state_r = Init; init_cnt = init_cnt + 1; end
2: begin state = Main; init_cnt = 0; end
endcase
Delay:
begin
if(delay_cnt == delay_num - 1)
begin
delay_cnt = 0;
state = state_r;
end
else
delay_cnt = delay_cnt + 1;
end
Sampling:
begin
if(sampling_cnt == sampling_num - 1)
begin
sampling_result = sampling_result + bus;
sampling_data = sampling_result > sampling_num >> 1 ? 1 : 0;
sampling_result = 0;
sampling_cnt = 0;
state = Read;
end
else
begin
sampling_result = sampling_result + bus;
sampling_cnt = sampling_cnt + 1;
end
end
Read:
case(read_cnt)
0: begin bus_output = LOW; state = Delay; delay_num = 4; state_r = Read; read_cnt = read_cnt + 1; end
1: begin bus_output = HIZ; state = Delay; delay_num = 4; state_r = Read; read_cnt = read_cnt + 1; end
2: begin state = Sampling; sampling_num = 4; read_cnt = read_cnt + 1; end
3: begin state = Delay; delay_num = 45; state_r = Read; read_cnt = read_cnt + 1; end
4: begin state = ReadData; read_cnt = 0; end
endcase
Write:
case(write_cnt)
0: begin bus_output = LOW; state = Delay; delay_num = 4; state_r = Write; write_cnt = write_cnt + 1; end
1: begin bus_output = data_buffer; state = Delay; delay_num = 54; state_r = Write; write_cnt = write_cnt + 1; end
2: begin bus_output = HIZ; state = WriteCmd; write_cnt = 0; end
endcase
Main:
case(main_cnt)
0: begin state = Init; main_cnt = main_cnt + 1; sig = 0; end
1: begin state = WriteCmd; cmd_buffer = 8'hcc; main_cnt = main_cnt + 1; end
2: begin state = WriteCmd; cmd_buffer = 8'h44; main_cnt = main_cnt + 1; end
3: begin state = Delay; delay_num = 750000; state_r = Main; main_cnt = main_cnt + 1; end
4: begin state = Init; main_cnt = main_cnt + 1; end
5: begin state = WriteCmd; cmd_buffer = 8'hcc; main_cnt = main_cnt + 1; end
6: begin state = WriteCmd; cmd_buffer = 8'hbe; main_cnt = main_cnt + 1; end
7: begin state = ReadData; main_cnt = main_cnt + 1; end
8:
begin
data_out_d[11:8] = data_out[11:4] / 100;
data_out_d[7:4] = data_out[11:4] / 10;
data_out_d[3:0] = data_out[11:4] % 10;
state = Main;
bus_output = HIZ;
init_cnt = 0;
delay_cnt = 0;
sampling_cnt = 0;
sampling_result = 0;
read_cnt = 0;
write_cnt = 0;
main_cnt = 0;
readdata_cnt = 0;
writecmd_cnt = 0;
sig = 1;
end
endcase
ReadData:
case(readdata_cnt)
0: begin state = Read; readdata_cnt = readdata_cnt + 1; end
16: begin data_out[readdata_cnt-1] = sampling_data; state = Main; readdata_cnt = 0; end
default: begin data_out[readdata_cnt-1] = sampling_data; state = Read; readdata_cnt = readdata_cnt + 1; end
endcase
WriteCmd:
case(writecmd_cnt)
8: begin state = Main; writecmd_cnt = 0; end
default: begin state = Write; data_buffer = cmd_buffer[writecmd_cnt]; writecmd_cnt = writecmd_cnt + 1; end
endcase
endcase
end
assign bus = bus_output;
endmodule
封装模块姑且目前就这些,剩下的就是统筹所有模块的Top级别模块了(干杂活)。记得东西多了一定打好分割线,避免混乱。
module MyTop(clk, rst_n, rxport, m_key, h_key, bus, cs, dc, sdin, oledrst, oledclk, txport, beeper);
input clk;
input rst_n;
input rxport;
input m_key;
input h_key;
inout bus;
output cs;
output dc;
output sdin;
output oledrst;
output oledclk;
output txport;
output beeper;
localparam Main = 3'b000;
localparam TimeAlert = 3'b001;
localparam TempeAlert = 3'b010;
localparam Delay = 3'b011;
localparam Init = 3'b100;
localparam Beeper = 3'b101;
wire [7:0] rx_wire;
wire [11:0] tempe_wire;
wire [15:0] mytime;
reg [11:0] mytime_r;
reg [15:0] tempe_buffer_r;
reg [5:0] rx_cnt;
reg [7:0] uart_rx_buffer [4:0];
reg [7:0] uart_tx_buffer;
reg [11:0] tempe_buffer;
reg [7:0] p_cnt;
reg [3:0] state;
reg [3:0] state_r;
reg [25:0] delay_num;
reg [25:0] delay_cnt;
reg [3:0] timealert_cnt;
reg send_sig;
reg [3:0] tempealert_cnt;
reg [20:0] beeper_cnt;
reg [20:0] beeper_num;
reg [20:0] beeper_cnt2;
reg beeper_2;
reg music_in;
initial
begin
rx_cnt = 0;
p_cnt = 0;
state = Init;
delay_cnt = 0;
timealert_cnt = 0;
tempealert_cnt = 0;
beeper_cnt = 0;
beeper_cnt2 = 0;
beeper_2 = 0;
music_in = 0;
end
// ---------------------------------------------------- CLK
MyClkDevide # (.width(4), .n(12)) u_clk_1 (clk, rst_n, clk_1_out);
MyClkDevide # (.width(12), .n(1250)) u_clk_2 (clk, rst_n, clk_2_out);
// ---------------------------------------------------- OLed
MyOLed u_oled (clk_1_out, rst_n, mytime_r, tempe_buffer_r, cs, dc, sdin, oledrst);
assign oledclk = clk_1_out;
// ---------------------------------------------------- Uart
MyUartTX u_uart_tx (clk_2_out, uart_tx_buffer, send_sig, rst_n, txport, t_busy);
MyUartRX u_uart_rx (clk, rst_n, rxport, rx_wire, r_busy);
always @ (negedge r_busy)
begin
uart_rx_buffer[rx_cnt] = rx_wire;
rx_cnt = rx_cnt + 1;
music_in = 1;
end
// ---------------------------------------------------- 18B20
My18B20 u_18b20 (clk_1_out, rst_n, bus, tempe_wire, sig);
always @ (posedge sig)
begin
tempe_buffer = tempe_wire;
end
assign overheat_sig = tempe_buffer[7:4] >= 3;
// ---------------------------------------------------- Clock
MyClock u_clock (clk, rst_n, m_key, h_key, mytime, time_sig);
// ---------------------------------------------------- Beeper
MyPWM u_beeper (clk_1_out, p_cnt, beeper_1);
assign beeper = beeper_1 || beeper_2;
// ----------------------------------------------------
always @ (posedge clk_1_out or negedge rst_n)
begin
if(!rst_n)
begin
p_cnt = 0;
state = Init;
delay_cnt = 0;
timealert_cnt = 0;
tempealert_cnt = 0;
beeper_cnt = 0;
beeper_cnt2 = 0;
beeper_2 = 0;
end
else
begin
if(state != TempeAlert)
begin
mytime_r = mytime;
tempe_buffer_r = tempe_buffer;
end
case(state)
Delay:
begin
if(delay_cnt == delay_num - 1)
begin
delay_cnt = 0;
state = state_r;
end
else
delay_cnt = delay_cnt + 1;
end
Main:
begin
if(time_sig)
state = TimeAlert;
else if(overheat_sig)
state = TempeAlert;
end
TimeAlert:
begin
case(timealert_cnt)
0: begin p_cnt = 50; uart_tx_buffer = tempe_buffer[7:0]; send_sig = 1; timealert_cnt = timealert_cnt + 1; end
1: begin state = Delay; delay_num = 100000; state_r = TimeAlert; timealert_cnt = timealert_cnt + 1; end
2: begin p_cnt = 0; if(!time_sig) timealert_cnt = timealert_cnt + 1; end
3: begin send_sig = 0; state = Main; timealert_cnt = 0; end
endcase
end
Init:
begin
state = Delay;
delay_num = 1000;
state_r = Main;
end
TempeAlert:
begin
case(tempealert_cnt)
0: begin uart_tx_buffer = 8'hFF; send_sig = 1; tempealert_cnt = tempealert_cnt + 1; end
1: begin state = Delay; delay_num = 1000; state_r = TempeAlert; tempealert_cnt = tempealert_cnt + 1; end
2: begin if(music_in) tempealert_cnt = tempealert_cnt + 1; end
8: begin if(!overheat_sig) tempealert_cnt = tempealert_cnt + 1; end
9: begin p_cnt = 0; state = Main; tempealert_cnt = 0; send_sig = 0; end
default:
begin
state = Beeper;
state_r = TempeAlert;
beeper_num = uart_rx_buffer[tempealert_cnt-3];
tempealert_cnt = tempealert_cnt + 1; end
endcase
end
Beeper:
begin
if(beeper_cnt2 == 1000000 / beeper_num)
begin
beeper_cnt = 0;
beeper_cnt2 = 0;
state = state_r;
end
else if(beeper_cnt == beeper_num - 1)
begin
beeper_cnt = 0;
beeper_cnt2 = beeper_cnt2 + 1;
end
else
beeper_cnt = beeper_cnt + 1;
beeper_2 = beeper_cnt > beeper_num >> 1 ? 1 : 0;
end
endcase
end
end
endmodule
遇到的困难:
这项目是我昨天刚刚推倒重做的,彻夜未眠。印象最深的就是晃眼睛的垃圾界面,还有不带提示的编程方式,自动排版都没有...
Verilog是一门神奇的语言,可能是因为我刚刚接触的原因,我觉得他特别能藏错。一开始我忘接线不报错整个人都是懵逼的。还有仿真这个东西,本以为是准确的,结果居然有一次出现了仿真和实际输出不一样的事情,害得我瞎改了半天(错的是真的离谱)。
此外,虽说Verilog挺像C语言,但感觉限制超多。对于我这种大一数电都没摸过的人来说简直要命。
好在撑过来了,尤其是最后一天的彻夜通宵,很过瘾。
展望:
这次项目的代码说实在的有很多冗余,是因为我不熟悉Verilog造成的。
Beeper其实可以独立出一个模块,但是因为时间原因没有做成。
貌似上面把心得体会都说了?没关系
心得体会:
多看文档