📄 chess_clock.txt
字号:
-- Chess Clock
-- some expressions can not be synthetized,only for Simulation. (such as "AFTER 500 ms")
-- download from: www.fpga.com.cn & www.pld.com.cn
PACKAGE chesspack IS
SUBTYPE hours IS NATURAL;
SUBTYPE minutes IS INTEGER RANGE 0 TO 60;
SUBTYPE seconds IS INTEGER RANGE 0 TO 60;
TYPE elapsed_time IS
RECORD
hh : hours;
mm : minutes;
ss : seconds;
END RECORD;
TYPE state IS (reset,hold,runb,runa);
FUNCTION inctime (intime : elapsed_time) RETURN elapsed_time;
FUNCTION zero_time RETURN elapsed_time;
END chesspack;
PACKAGE BODY chesspack IS
FUNCTION inctime (intime :elapsed_time) RETURN elapsed_time IS
VARIABLE result : elapsed_time;
BEGIN
result := intime;
result.ss := result.ss + 1;
IF result.ss = 60 THEN
result.ss := 0;
result.mm := result.mm + 1;
IF result.mm = 60 THEN
result.mm := 0;
result.hh := result.hh + 1;
END IF;
END IF;
RETURN result;
END inctime;
FUNCTION zero_time RETURN elapsed_time IS
VARIABLE result : elapsed_time;
BEGIN
result.ss := 0;
result.mm := 0;
result.hh := 0;
RETURN result;
END zero_time;
END chesspack;
USE WORK.chesspack.ALL;
ENTITY timer IS
--time_used must be inout port since signal assignment statement
--reads it's value to compute the new value of time_used.
PORT(enable,clear,one_sec : IN BIT; time_used : INOUT elapsed_time);
END timer;
ARCHITECTURE behaviour OF timer IS
BEGIN
time_used <= zero_time WHEN clear = '1' ELSE
inctime(time_used) WHEN
(enable = '1' AND one_sec'EVENT AND one_sec = '1')
ELSE time_used;
END behaviour;
------------------------------------------------------------------
USE WORK.chesspack.ALL;
ENTITY chessclock IS
PORT(a,b,hold_time,reset_time : IN BIT;
time_a,time_b : INOUT elapsed_time);
END chessclock;
ARCHITECTURE structure OF chessclock IS
COMPONENT timer
PORT(enable,clear,one_sec : IN BIT; time_used : INOUT elapsed_time);
END COMPONENT;
SIGNAL one_sec,clock,ena,enb,clear_timers : BIT := '0';
BEGIN
--instantiating timers a and b
timer_a : timer PORT MAP(ena,clear_timers,one_sec,time_a);
timer_b : timer PORT MAP(enb,clear_timers,one_sec,time_b);
controller:BLOCK --chessclock state machine
SIGNAL present_state,next_state : state := reset;
BEGIN
--state register
state_reg:BLOCK
BEGIN
PROCESS(clock)
BEGIN
IF (clock'EVENT AND clock = '1' AND clock'LAST_VALUE = '0')
THEN present_state <= next_state;
END IF;
END PROCESS;
END BLOCK state_reg;
--output and feedback logic
logic:BLOCK
BEGIN
PROCESS(a,b,hold_time,reset_time,present_state)
VARIABLE a_b : BIT_VECTOR(0 TO 1);
BEGIN
a_b := a&b; --aggregate assignment for case statement
CASE present_state IS
WHEN reset =>
clear_timers <= '1';
ena <= '0';
enb <= '0';
IF reset_time = '1' THEN next_state <= reset;
ELSIF hold_time = '1' THEN next_state <= hold;
ELSE CASE a_b IS
WHEN "00" => next_state <= hold;
WHEN "01" => next_state <= runa;
WHEN "10" => next_state <= runb;
WHEN "11" => next_state <= hold;
END CASE;
END IF;
WHEN hold =>
clear_timers <= '0';
ena <= '0';
enb <= '0';
IF reset_time = '1' THEN next_state <= reset;
ELSIF hold_time = '1' THEN next_state <= hold;
ELSE CASE a_b IS
WHEN "00" => next_state <= hold;
WHEN "01" => next_state <= runa;
WHEN "10" => next_state <= runb;
WHEN "11" => next_state <= hold;
END CASE;
END IF;
WHEN runa =>
clear_timers <= '0';
ena <= '1';
enb <= '0';
IF reset_time = '1' THEN next_state <= reset;
ELSIF hold_time = '1' THEN next_state <= hold;
ELSIF a = '0' THEN next_state <= runa;
ELSIF b = '1' THEN next_state <= hold;
ELSE next_state <= runb;
END IF;
WHEN runb =>
clear_timers <= '0';
ena <= '0';
enb <= '1';
IF reset_time = '1' THEN next_state <= reset;
ELSIF hold_time = '1' THEN next_state <= hold;
ELSIF b = '0' THEN next_state <= runb;
ELSIF a = '1' THEN next_state <= hold;
ELSE next_state <= runa;
END IF;
END CASE;
END PROCESS;
END BLOCK logic;
END BLOCK controller;
one_sec_clock:BLOCK
BEGIN
PROCESS --process to generate one second clock
BEGIN
one_sec <= TRANSPORT '1' AFTER 500 ms;
one_sec <= TRANSPORT '0' AFTER 1000 ms;
WAIT FOR 1000 ms;
END PROCESS;
END BLOCK one_sec_clock;
system_clock:BLOCK
BEGIN
PROCESS --process to generate 10Hz state machine clock
BEGIN
clock <= TRANSPORT '1' AFTER 50 ms;
clock <= TRANSPORT '0' AFTER 100 ms;
WAIT FOR 100 ms;
END PROCESS;
END BLOCK system_clock;
END structure;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -