// digital clock using LCD display
//digit_clock ( CLOCK_50, SW, KEY,
// HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6,
HEX7,
// temp_h1, temp_h0, temp_m1, temp_m0,
// temp_s1, temp_s0, temp_tsec);
module lab5_3(KEY,SW, CLOCK_50, LCD_RS,
LCD_EN, LCD_ON, LCD_RW, LCD_DATA,
HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6,
HEX7);
input
[0:0] SW;
input
[2:0] KEY;
input
CLOCK_50;
output
LCD_RS, LCD_EN, LCD_ON, LCD_RW;
output
[7:0] LCD_DATA;
output
[0:6] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7;
wire
CLK_400Hz;
reg
[5:0] p_state, n_state;
wire
[3:0] bcd_hrd1, bcd_hrd0, bcd_mind1, bcd_mind0, bcd_secd1, bcd_secd0;
clock
clk400 (CLOCK_50, 62500, CLK_400Hz);
digit_clock
u0 ( CLOCK_50, SW, KEY[2:1],
HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6,
HEX7,
bcd_hrd1, bcd_hrd0, bcd_mind1, bcd_mind0,
bcd_secd1, bcd_secd0);
fsm_lcd
u1 (CLK_400Hz, KEY[0],
bcd_hrd1,
bcd_hrd0, bcd_mind1, bcd_mind0, bcd_secd1, bcd_secd0,
LCD_ON,
LCD_RS, LCD_EN, LCD_RW, LCD_DATA);
endmodule
module clock(input cclk, input[31:0]
clkscale, output reg clk);
reg[31:0]clkq=0;
always@(posedge
cclk)
begin
clkq=clkq+1;
if(clkq>=clkscale)
begin
clk=~clk;
clkq=0;
end
end
endmodule
//digital clock with preset by pushbuttons
module digit_clock ( CLOCK_50, SW, KEY,
HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6,
HEX7,
temp_h1, temp_h0, temp_m1, temp_m0,
temp_s1, temp_s0 /*, temp_tsec*/);
input
CLOCK_50; // 50MHz clock
input
[1:0] KEY;
input [0:0] SW;
// SW[17]=1 preset time, SW[17]=0 normally works as clock
// SW[15:12] for hour1, SW[11:8] for hour0
// SW[7:4] for minute1, SW[3:0] for minute0
output [0:6] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7;
//
HEX5 HEX4 for hour
//
HEX3 HEX2 for minute
//
HEX1 HEX0 for second
output reg [3:0] temp_h1, temp_h0, temp_m1, temp_m0, temp_s1, temp_s0/*,
temp_tsec*/;
reg [3:0] h1, h0, m1, m0;
clock M0 (CLOCK_50, 25000000, clock_1Hz);
// generate 10Hz clock
seg7 hour1 (temp_h1, HEX7);
seg7
hour0(temp_h0, HEX6);
seg7
minute1(temp_m1, HEX5);
seg7
minute0(temp_m0, HEX4);
seg7
second1(temp_s1, HEX3);
seg7
second0(temp_s0, HEX2);
//
seg7 tsec(temp_tsec, HEX0);
assign HEX1=7'b1111111;
assign
HEX0=7'b1111111;
//set minutes
always @ (posedge KEY[0])
begin
m0
= m0+1;
if(m0==10)
begin
m0 = 0;
m1 = m1+1;
end
if(m1 == 6) m1=0;
end
// set hours
always @ (posedge KEY[1])
begin
h0
= h0+1;
if(h0==10)
begin
h0 = 0;
h1 = h1+1;
end
if(h1 == 2 && h0==4)
begin
h1=0;
h0=0;
end
end
always @ (posedge clock_1Hz)
begin
if(SW[0])
begin
temp_h1=h1;
temp_h0=h0;
temp_m1=m1;
temp_m0=m0;
/*temp_tsec=0;*/
temp_s1=0;
temp_s0=0;
end
else
begin
/* temp_tsec=temp_tsec+1;
if
(temp_tsec ==10)
begin
temp_tsec
= 0;
*/
temp_s0=temp_s0+1;
if
(temp_s0 == 10)
begin
temp_s0
= 0;
temp_s1
= temp_s1+1;
if
(temp_s1 == 6)
begin
temp_s1
= 0;
temp_m0
=temp_m0+1;
if
(temp_m0 ==10)
begin
temp_m0
= 0;
temp_m1
= temp_m1+1;
if(temp_m1
== 6)
begin
temp_m1
= 0;
temp_h0
= temp_h0+1;
if((temp_h1
<= 1) && (temp_h0 == 10))
begin
temp_h0
=0;
temp_h1
= temp_h1+1;
end
else
if (temp_h1==2 && temp_h0==4)
begin
temp_h0
=0;
temp_h1
=0;
end
end
end
end
end
end
end
/*end*/
Endmodule
// FSM to control LCD for display time h1h0:mim0:s1s0
module fsm_lcd(CLK_400Hz, resetn,
bcd_hrd1,
bcd_hrd0, bcd_mind1, bcd_mind0, bcd_secd1, bcd_secd0,
LCD_ON,
LCD_RS, LCD_EN, LCD_RW, LCD_DATA);
input
CLK_400Hz, resetn;
input
[3:0] bcd_hrd1, bcd_hrd0, bcd_mind1, bcd_mind0, bcd_secd1, bcd_secd0;
output
LCD_ON, LCD_RS, LCD_EN, LCD_RW;
output
[7:0] LCD_DATA;
reg
[5:0] p_state, n_state;
reg LCD_EN, LCD_RS;
reg [7:0]
LCD_DATA_VALUE;
parameter
[5:0] reset1=1, reset2=2, reset3=3, FUNC_SET=4,
display_off=5,
display_clear=6,
display_on=7,
mode_set=8, write_char1=9,
write_char2=10,
write_char3=11, write_char4=12,
write_char5=13, write_char6=14,
write_char7=15,
write_char8=16,
write_char9=17, write_char10=18,
return_home=19,
toggle_e1=20,toggle_e2=21,
toggle_e3=22, toggle_e4=23,
toggle_e5=24,toggle_e6=25,
toggle_e7=26, toggle_e8=27,
toggle_e9=28,toggle_e10=29,
toggle_e11=30, toggle_e12=31,
toggle_e13=32,toggle_e14=33,
toggle_e15=34, toggle_e16=35,
toggle_e17=36,toggle_e18=37,
toggle_e19=38, w_address=39,
write_w=40;
parameter [5:0]
toggle_e20=41, toggle_e21=42, char1_address=43, write_e=44;
assign
LCD_ON=1;
assign
LCD_RW=0;
assign
LCD_DATA = LCD_RW? 8'bzzzzzzzz: LCD_DATA_VALUE;
always
@ (p_state)
begin
case
(p_state)
reset1:
begin
n_state
= toggle_e1;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h38;
end
toggle_e1:
begin
n_state
= reset2;
{LCD_EN,
LCD_RS}=2'b00;
LCD_DATA_VALUE
= 8'h38;
end
reset2:
begin
n_state
= toggle_e2;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h38;
end
toggle_e2:
begin
n_state
= reset3;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h38;
end
reset3:
begin
n_state
= toggle_e3;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h38;
end
toggle_e3:
begin
n_state
= FUNC_SET;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h38;
end
FUNC_SET:
begin
n_state
= toggle_e4;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h38;
end
toggle_e4:
begin
n_state
= display_off;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h38;
end
display_off:
begin
n_state
= toggle_e5;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h08;
end
toggle_e5:
begin
n_state
= display_clear;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h08;
end
display_clear:
begin
n_state
= toggle_e6;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h01;
end
toggle_e6:
begin
n_state
= display_on;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h01;
end
display_on:
begin
n_state
= toggle_e7;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h0c;
end
toggle_e7:
begin
n_state
= mode_set;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h0c;
end
mode_set:
begin
n_state
= toggle_e8;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE = 8'h06;
end
toggle_e8:
begin
n_state
= /*char1_address;*/write_char1;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE = 8'h06;
end
/*//
to display time in the center of the line
char1_address:
begin
n_state
= toggle_e19;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE =8'h80;
end
toggle_e19:
begin
n_state
= write_char1;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE =8'h80;
end
*/
write_char1:
begin
n_state
= toggle_e9;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = {3'b011, bcd_hrd1};
end
toggle_e9:
begin
n_state
= write_char2;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = {3'b011, bcd_hrd1};
end
write_char2:
begin
n_state
= toggle_e10;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = {3'b011, bcd_hrd0};
end
toggle_e10:
begin
n_state
= write_char3;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = {3'b011, bcd_hrd0};
end
write_char3:
begin
n_state
= toggle_e11;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = 8'h3a;
end
toggle_e11:
begin
n_state
= write_char4;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = 8'h3a;
end
write_char4:
begin
n_state
= toggle_e12;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = {3'b011, bcd_mind1};
end
toggle_e12:
begin
n_state
= write_char5;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = {3'b011, bcd_mind1};
end
write_char5:
begin
n_state
= toggle_e13;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = {3'b011, bcd_mind0};
end
toggle_e13:
begin
n_state
= write_char6;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = {3'b011, bcd_mind0};
end
write_char6:
begin
n_state
= toggle_e14;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE = 8'h3a;
end
toggle_e14:
begin
n_state
= write_char7;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE = 8'h3a;
end
write_char7:
begin
n_state
= toggle_e15;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE ={3'b011, bcd_secd1};
end
toggle_e15:
begin
n_state
= write_char8;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE ={3'b011, bcd_secd1};
end
write_char8:
begin
n_state
= toggle_e16;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE ={3'b011, bcd_secd0};
end
toggle_e16:
begin
n_state
= w_address;
{LCD_EN, LCD_RS}=2'b01;
LCD_DATA_VALUE ={3'b011, bcd_secd0};
end
//
set DDRAM address for the second line
//
w_address:
begin
n_state
= toggle_e17;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE =8'hc0;
end
toggle_e17:
begin
n_state
= write_w;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE =8'hc0;
end
write_w:
begin
n_state
= toggle_e18;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE =8'h57;
end
toggle_e18:
begin
n_state
= write_e;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE =8'h57;
end
write_e:
begin
n_state
= toggle_e20;
{LCD_EN, LCD_RS}=2'b11;
LCD_DATA_VALUE =8'h65;
end
toggle_e20:
begin
n_state
= return_home;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE =8'h65;
end
return_home:
begin
n_state
= toggle_e21;
{LCD_EN, LCD_RS}=2'b10;
LCD_DATA_VALUE =8'h80; //8'h80;
end
toggle_e21:
begin
n_state
= write_char1;
{LCD_EN, LCD_RS}=2'b00;
LCD_DATA_VALUE =8'h80;//8'h80;
end
endcase
end
always
@ (posedge CLK_400Hz, negedge resetn)
begin
if
(resetn == 0)
begin
p_state
<= reset1;
end
else
p_state
<= n_state;
end
endmodule
module seg7 (bcd, leds_out);
input
[3:0] bcd;
output
[0:6] leds_out;
reg
[0:6] leds;
always
@(bcd)
case
(bcd) //abcdefg
0:
leds = 7'b1111110;
1:
leds = 7'b0110000;
2:
leds = 7'b1101101;
3:
leds = 7'b1111001;
4:
leds = 7'b0110011;
5:
leds = 7'b1011011;
6:
leds = 7'b1011111;
7:
leds = 7'b1110000;
8:
leds = 7'b1111111;
9:
leds = 7'b1111011;
10:
leds =7'b1110111;
11:
leds =7'b0011111;
12:
leds =7'b1001110;
13:
leds =7'b0111101;
14:
leds =7'b1001111;
15:
leds =7'b1000111;
default:
leds = 7'bx;
endcase
assign
leds_out = ~ leds;
endmodule
沒有留言:
張貼留言