mirror of https://github.com/zxdos/zxuno.git
Añado ch06
This commit is contained in:
parent
5edd995303
commit
e63fc46a15
|
@ -11,5 +11,5 @@ goto :eof
|
||||||
SET machine=%1
|
SET machine=%1
|
||||||
call %ruta_bat%genxst.bat
|
call %ruta_bat%genxst.bat
|
||||||
call %ruta_bat%generar.bat v4 ZX1
|
call %ruta_bat%generar.bat v4 ZX1
|
||||||
copy /y COREn.ZX1 %machine%.ZX1
|
copy /y COREn.ZX1 %ruta_ucf%_%machine%.ZX1
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|
|
@ -11,5 +11,5 @@ goto :eof
|
||||||
SET machine=%1
|
SET machine=%1
|
||||||
call %ruta_bat%genxst.bat
|
call %ruta_bat%genxst.bat
|
||||||
call %ruta_bat%generar.bat v4 ZX1
|
call %ruta_bat%generar.bat v4 ZX1
|
||||||
copy /y COREn.ZX1 %machine%.ZX1
|
copy /y COREn.ZX1 %ruta_ucf%_%machine%.ZX1
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|
|
@ -13,16 +13,6 @@ NET "bot<2>" LOC="P1" | IOSTANDARD=LVCMOS33 | PULLUP; #up
|
||||||
NET "bot<3>" LOC="P5" | IOSTANDARD=LVCMOS33 | PULLUP; #down
|
NET "bot<3>" LOC="P5" | IOSTANDARD=LVCMOS33 | PULLUP; #down
|
||||||
NET "bot<4>" LOC="P2" | IOSTANDARD=LVCMOS33 | PULLUP; #fire
|
NET "bot<4>" LOC="P2" | IOSTANDARD=LVCMOS33 | PULLUP; #fire
|
||||||
|
|
||||||
# 8 slide switches
|
|
||||||
NET "sw<0>" LOC="P51" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<1>" LOC="P46" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<2>" LOC="P45" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<3>" LOC="P50" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<4>" LOC="P48" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<5>" LOC="P57" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<6>" LOC="P56" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
NET "sw<7>" LOC="P58" | IOSTANDARD=LVCMOS33 | PULLUP;
|
|
||||||
|
|
||||||
#========================================================
|
#========================================================
|
||||||
# 4-digit time-multiplexed 7-segment LED display
|
# 4-digit time-multiplexed 7-segment LED display
|
||||||
#========================================================
|
#========================================================
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
vhdl work "list_ch05_07_db_test.vhd"
|
vhdl work "list_ch05_07_db_test.vhd"
|
||||||
vhdl work "list_ch05_06_debounce.vhd"
|
vhdl work "list_ch05_06_debounce.vhd"
|
||||||
|
vhdl work "../ch04/list_ch04_15_disp_hex.vhd"
|
||||||
|
|
|
@ -33,7 +33,8 @@ begin
|
||||||
clk=>clk, reset=>'0',
|
clk=>clk, reset=>'0',
|
||||||
hex3=>b_count(7 downto 4), hex2=>b_count(3 downto 0),
|
hex3=>b_count(7 downto 4), hex2=>b_count(3 downto 0),
|
||||||
hex1=>d_count(7 downto 4), hex0=>d_count(3 downto 0),
|
hex1=>d_count(7 downto 4), hex0=>d_count(3 downto 0),
|
||||||
dp_in=>"1011", an=>an, sseg=>sseg);
|
point=>'1', colon=>'0',
|
||||||
|
an=>an, sseg=>sseg);
|
||||||
-- instantiate debouncing circuit
|
-- instantiate debouncing circuit
|
||||||
db_unit: entity work.db_fsm(arch)
|
db_unit: entity work.db_fsm(arch)
|
||||||
port map(
|
port map(
|
||||||
|
|
|
@ -8,5 +8,5 @@ goto :eof
|
||||||
SET machine=%1
|
SET machine=%1
|
||||||
call %ruta_bat%genxst.bat
|
call %ruta_bat%genxst.bat
|
||||||
call %ruta_bat%generar.bat v4 ZX1
|
call %ruta_bat%generar.bat v4 ZX1
|
||||||
copy /y COREn.ZX1 %machine%.ZX1
|
copy /y COREn.ZX1 %ruta_ucf%_%machine%.ZX1
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#========================================================
|
||||||
|
# clock
|
||||||
|
#========================================================
|
||||||
|
NET "clk" LOC="P55" | IOSTANDARD=LVCMOS33;
|
||||||
|
|
||||||
|
#========================================================
|
||||||
|
# buttons & switches
|
||||||
|
#========================================================
|
||||||
|
# 5 push buttons
|
||||||
|
NET "bot<0>" LOC="P6" | IOSTANDARD=LVCMOS33 | PULLUP; #left
|
||||||
|
NET "bot<1>" LOC="P7" | IOSTANDARD=LVCMOS33 | PULLUP; #right
|
||||||
|
NET "bot<2>" LOC="P1" | IOSTANDARD=LVCMOS33 | PULLUP; #up
|
||||||
|
NET "bot<3>" LOC="P5" | IOSTANDARD=LVCMOS33 | PULLUP; #down
|
||||||
|
NET "bot<4>" LOC="P2" | IOSTANDARD=LVCMOS33 | PULLUP; #fire
|
||||||
|
|
||||||
|
#========================================================
|
||||||
|
# 4-digit time-multiplexed 7-segment LED display
|
||||||
|
#========================================================
|
||||||
|
# digit enable
|
||||||
|
NET "an<0>" LOC="P30" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "an<1>" LOC="P29" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "an<2>" LOC="P15" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "an<3>" LOC="P32" | IOSTANDARD=LVCMOS33;
|
||||||
|
|
||||||
|
# 7-segment led segments
|
||||||
|
NET "sseg<7>" LOC="P23" | IOSTANDARD=LVCMOS33; # decimal point
|
||||||
|
NET "sseg<6>" LOC="P16" | IOSTANDARD=LVCMOS33; # segment a
|
||||||
|
NET "sseg<5>" LOC="P22" | IOSTANDARD=LVCMOS33; # segment b
|
||||||
|
NET "sseg<4>" LOC="P24" | IOSTANDARD=LVCMOS33; # segment c
|
||||||
|
NET "sseg<3>" LOC="P12" | IOSTANDARD=LVCMOS33; # segment d
|
||||||
|
NET "sseg<2>" LOC="P21" | IOSTANDARD=LVCMOS33; # segment e
|
||||||
|
NET "sseg<1>" LOC="P26" | IOSTANDARD=LVCMOS33; # segment f
|
||||||
|
NET "sseg<0>" LOC="P27" | IOSTANDARD=LVCMOS33; # segment g
|
||||||
|
|
||||||
|
#========================================================
|
||||||
|
# 5 discrete led
|
||||||
|
#========================================================
|
||||||
|
NET "led<0>" LOC="P34" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "led<1>" LOC="P35" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "led<2>" LOC="P41" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "led<3>" LOC="P43" | IOSTANDARD=LVCMOS33;
|
||||||
|
NET "led<4>" LOC="P47" | IOSTANDARD=LVCMOS33;
|
|
@ -0,0 +1,2 @@
|
||||||
|
vhdl work "list_ch06_03_db_test.vhd"
|
||||||
|
vhdl work "list_ch06_01_02_debounce.vhd"
|
|
@ -0,0 +1,30 @@
|
||||||
|
-w
|
||||||
|
-g Binary:no
|
||||||
|
-g Compress
|
||||||
|
-g CRC:Enable
|
||||||
|
-g Reset_on_err:No
|
||||||
|
-g ConfigRate:2
|
||||||
|
-g ProgPin:PullUp
|
||||||
|
-g TckPin:PullUp
|
||||||
|
-g TdiPin:PullUp
|
||||||
|
-g TdoPin:PullUp
|
||||||
|
-g TmsPin:PullUp
|
||||||
|
-g UnusedPin:PullDown
|
||||||
|
-g UserID:0xFFFFFFFF
|
||||||
|
-g ExtMasterCclk_en:No
|
||||||
|
-g SPI_buswidth:1
|
||||||
|
-g TIMER_CFG:0xFFFF
|
||||||
|
-g multipin_wakeup:No
|
||||||
|
-g StartUpClk:CClk
|
||||||
|
-g DONE_cycle:4
|
||||||
|
-g GTS_cycle:5
|
||||||
|
-g GWE_cycle:6
|
||||||
|
-g LCK_cycle:NoWait
|
||||||
|
-g Security:None
|
||||||
|
-g DonePipe:No
|
||||||
|
-g DriveDone:No
|
||||||
|
-g en_sw_gsr:No
|
||||||
|
-g drive_awake:No
|
||||||
|
-g sw_clk:Startupclk
|
||||||
|
-g sw_gwe_cycle:5
|
||||||
|
-g sw_gts_cycle:4
|
|
@ -0,0 +1,53 @@
|
||||||
|
set -tmpdir "projnav.tmp"
|
||||||
|
set -xsthdpdir "xst"
|
||||||
|
run
|
||||||
|
-ifn debounce_test.prj
|
||||||
|
-infer_ramb8 No -loop_iteration_limit 32768
|
||||||
|
-ofn debounce_test
|
||||||
|
-ofmt NGC
|
||||||
|
-p xc6slx9-2-tqg144
|
||||||
|
-top debounce_test
|
||||||
|
-opt_mode Speed
|
||||||
|
-opt_level 2
|
||||||
|
-power NO
|
||||||
|
-uc "timings.xcf"
|
||||||
|
-iuc NO
|
||||||
|
-keep_hierarchy No
|
||||||
|
-netlist_hierarchy As_Optimized
|
||||||
|
-rtlview Yes
|
||||||
|
-glob_opt AllClockNets
|
||||||
|
-read_cores YES
|
||||||
|
-write_timing_constraints YES
|
||||||
|
-cross_clock_analysis NO
|
||||||
|
-hierarchy_separator /
|
||||||
|
-bus_delimiter <>
|
||||||
|
-case Maintain
|
||||||
|
-slice_utilization_ratio 100
|
||||||
|
-bram_utilization_ratio 100
|
||||||
|
-dsp_utilization_ratio 100
|
||||||
|
-lc Auto
|
||||||
|
-reduce_control_sets Auto
|
||||||
|
-fsm_extract NO
|
||||||
|
-fsm_style LUT
|
||||||
|
-ram_extract Yes
|
||||||
|
-ram_style Auto
|
||||||
|
-rom_extract Yes
|
||||||
|
-shreg_extract YES
|
||||||
|
-rom_style Auto
|
||||||
|
-auto_bram_packing NO
|
||||||
|
-resource_sharing YES
|
||||||
|
-async_to_sync YES
|
||||||
|
-shreg_min_size 2
|
||||||
|
-use_dsp48 Auto
|
||||||
|
-iobuf YES
|
||||||
|
-max_fanout 100000
|
||||||
|
-bufg 16
|
||||||
|
-register_duplication YES
|
||||||
|
-register_balancing No
|
||||||
|
-optimize_primitives NO
|
||||||
|
-use_clock_enable Auto
|
||||||
|
-use_sync_set Auto
|
||||||
|
-use_sync_reset Auto
|
||||||
|
-iob Auto
|
||||||
|
-equivalent_register_removal YES
|
||||||
|
-slice_utilization_ratio_maxmargin 5
|
|
@ -0,0 +1,145 @@
|
||||||
|
-- Listing 6.1
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity debounce is
|
||||||
|
port(
|
||||||
|
clk, reset: in std_logic;
|
||||||
|
sw: in std_logic;
|
||||||
|
db_level, db_tick: out std_logic
|
||||||
|
);
|
||||||
|
end debounce ;
|
||||||
|
|
||||||
|
architecture exp_fsmd_arch of debounce is
|
||||||
|
constant N: integer:=21; -- filter of 2^N * 20ns = 20ms
|
||||||
|
type state_type is (zero, wait0, one, wait1);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal q_reg, q_next: unsigned(N-1 downto 0);
|
||||||
|
signal q_load, q_dec, q_zero: std_logic;
|
||||||
|
begin
|
||||||
|
-- FSMD state & data registers
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= zero;
|
||||||
|
q_reg <= (others=>'0');
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
q_reg <= q_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- FSMD data path (counter) next-state logic
|
||||||
|
q_next <= (others=>'1') when q_load='1' else
|
||||||
|
q_reg - 1 when q_dec='1' else
|
||||||
|
q_reg;
|
||||||
|
q_zero <= '1' when q_next=0 else '0';
|
||||||
|
|
||||||
|
-- FSMD control path next-state logic
|
||||||
|
process(state_reg,sw,q_zero)
|
||||||
|
begin
|
||||||
|
q_load <= '0';
|
||||||
|
q_dec <= '0';
|
||||||
|
db_tick <= '0';
|
||||||
|
state_next <= state_reg;
|
||||||
|
case state_reg is
|
||||||
|
when zero =>
|
||||||
|
db_level <= '0';
|
||||||
|
if (sw='1') then
|
||||||
|
state_next <= wait1;
|
||||||
|
q_load <= '1';
|
||||||
|
end if;
|
||||||
|
when wait1=>
|
||||||
|
db_level <= '0';
|
||||||
|
if (sw='1') then
|
||||||
|
q_dec <= '1';
|
||||||
|
if (q_zero='1') then
|
||||||
|
state_next <= one;
|
||||||
|
db_tick <= '1';
|
||||||
|
end if;
|
||||||
|
else -- sw='0'
|
||||||
|
state_next <= zero;
|
||||||
|
end if;
|
||||||
|
when one =>
|
||||||
|
db_level <= '1';
|
||||||
|
if (sw='0') then
|
||||||
|
state_next <= wait0;
|
||||||
|
q_load <= '1';
|
||||||
|
end if;
|
||||||
|
when wait0=>
|
||||||
|
db_level <= '1';
|
||||||
|
if (sw='0') then
|
||||||
|
q_dec <= '1';
|
||||||
|
if (q_zero='1') then
|
||||||
|
state_next <= zero;
|
||||||
|
end if;
|
||||||
|
else -- sw='1'
|
||||||
|
state_next <= one;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
end exp_fsmd_arch;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Listing 6.2
|
||||||
|
architecture fsmd_arch of debounce is
|
||||||
|
constant N: integer:=21; -- filter of 2^N * 20ns = 40ms
|
||||||
|
type state_type is (zero, wait0, one, wait1);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal q_reg, q_next: unsigned(N-1 downto 0);
|
||||||
|
begin
|
||||||
|
-- FSMD state & data registers
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= zero;
|
||||||
|
q_reg <= (others=>'0');
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
q_reg <= q_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
-- next-state logic & data path functional units/routing
|
||||||
|
process(state_reg,q_reg,sw,q_next)
|
||||||
|
begin
|
||||||
|
state_next <= state_reg;
|
||||||
|
q_next <= q_reg;
|
||||||
|
db_tick <= '0';
|
||||||
|
case state_reg is
|
||||||
|
when zero =>
|
||||||
|
db_level <= '0';
|
||||||
|
if (sw='1') then
|
||||||
|
state_next <= wait1;
|
||||||
|
q_next <= (others=>'1');
|
||||||
|
end if;
|
||||||
|
when wait1=>
|
||||||
|
db_level <= '0';
|
||||||
|
if (sw='1') then
|
||||||
|
q_next <= q_reg - 1;
|
||||||
|
if (q_next=0) then
|
||||||
|
state_next <= one;
|
||||||
|
db_tick <= '1';
|
||||||
|
end if;
|
||||||
|
else -- sw='0'
|
||||||
|
state_next <= zero;
|
||||||
|
end if;
|
||||||
|
when one =>
|
||||||
|
db_level <= '1';
|
||||||
|
if (sw='0') then
|
||||||
|
state_next <= wait0;
|
||||||
|
q_next <= (others=>'1');
|
||||||
|
end if;
|
||||||
|
when wait0=>
|
||||||
|
db_level <= '1';
|
||||||
|
if (sw='0') then
|
||||||
|
q_next <= q_reg - 1;
|
||||||
|
if (q_next=0) then
|
||||||
|
state_next <= zero;
|
||||||
|
end if;
|
||||||
|
else -- sw='1'
|
||||||
|
state_next <= one;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
end fsmd_arch;
|
|
@ -0,0 +1,69 @@
|
||||||
|
-- Listing 6.3
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity debounce_test is
|
||||||
|
port(
|
||||||
|
clk: in std_logic;
|
||||||
|
btn: in std_logic_vector(3 downto 0);
|
||||||
|
an: out std_logic_vector(3 downto 0);
|
||||||
|
sseg: out std_logic_vector(7 downto 0)
|
||||||
|
);
|
||||||
|
end debounce_test;
|
||||||
|
|
||||||
|
architecture arch of debounce_test is
|
||||||
|
signal q1_reg, q1_next: unsigned(7 downto 0);
|
||||||
|
signal q0_reg, q0_next: unsigned(7 downto 0);
|
||||||
|
signal b_count, d_count: std_logic_vector(7 downto 0);
|
||||||
|
signal btn_reg: std_logic;
|
||||||
|
signal db_tick, btn_tick, clr: std_logic;
|
||||||
|
-- Listing 7.3
|
||||||
|
begin
|
||||||
|
-- instantiate debouncing circuit
|
||||||
|
db_unit: entity work.debounce(fsmd_arch)
|
||||||
|
port map(
|
||||||
|
clk=>clk, reset=>'0', sw=>btn(1),
|
||||||
|
db_level=> open, db_tick=>db_tick
|
||||||
|
);
|
||||||
|
-- instantiate hex display time-multiplxing circuit
|
||||||
|
disp_unit: entity work.disp_hex_mux
|
||||||
|
port map(
|
||||||
|
clk=>clk, reset=>'0',
|
||||||
|
hex3=>b_count(7 downto 4), hex2=>b_count(3 downto 0),
|
||||||
|
hex1=>d_count(7 downto 4), hex0=>d_count(3 downto 0),
|
||||||
|
dp_in=>"1011", an=>an, sseg=>sseg
|
||||||
|
);
|
||||||
|
|
||||||
|
--=================================================
|
||||||
|
-- edge detection circuit for un-debounced input
|
||||||
|
--=================================================
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if (clk'event and clk='1') then
|
||||||
|
btn_reg <= btn(1);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
btn_tick <= (not btn_reg) and btn(1);
|
||||||
|
|
||||||
|
--=================================================
|
||||||
|
-- two counters
|
||||||
|
--=================================================
|
||||||
|
clr <= btn(0);
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if (clk'event and clk='1') then
|
||||||
|
q1_reg <= q1_next;
|
||||||
|
q0_reg <= q0_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
-- next-state logic for the counter
|
||||||
|
q1_next <= (others=>'0') when clr='1' else
|
||||||
|
q1_reg + 1 when btn_tick='1' else
|
||||||
|
q1_reg;
|
||||||
|
q0_next <= (others=>'0') when clr='1' else
|
||||||
|
q0_reg + 1 when db_tick='1' else
|
||||||
|
q0_reg;
|
||||||
|
-- counter output
|
||||||
|
b_count <= std_logic_vector(q1_reg);
|
||||||
|
d_count <= std_logic_vector(q0_reg);
|
||||||
|
end arch;
|
|
@ -0,0 +1,72 @@
|
||||||
|
-- Listing 6.4
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity fib is
|
||||||
|
port(
|
||||||
|
clk, reset: in std_logic;
|
||||||
|
start: in std_logic;
|
||||||
|
i: in std_logic_vector(4 downto 0);
|
||||||
|
ready, done_tick: out std_logic;
|
||||||
|
f: out std_logic_vector(19 downto 0)
|
||||||
|
);
|
||||||
|
end fib;
|
||||||
|
|
||||||
|
architecture arch of fib is
|
||||||
|
type state_type is (idle,op,done);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal t0_reg, t0_next, t1_reg, t1_next: unsigned(19 downto 0);
|
||||||
|
signal n_reg, n_next: unsigned(4 downto 0);
|
||||||
|
begin
|
||||||
|
-- fsmd state and data registers
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= idle;
|
||||||
|
t0_reg <= (others=>'0');
|
||||||
|
t1_reg <= (others=>'0');
|
||||||
|
n_reg <= (others=>'0');
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
t0_reg <= t0_next;
|
||||||
|
t1_reg <= t1_next;
|
||||||
|
n_reg <= n_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
-- fsmd next-state logic
|
||||||
|
process(state_reg,n_reg,t0_reg,t1_reg,start,i,n_next)
|
||||||
|
begin
|
||||||
|
ready <='0';
|
||||||
|
done_tick <= '0';
|
||||||
|
state_next <= state_reg;
|
||||||
|
t0_next <= t0_reg;
|
||||||
|
t1_next <= t1_reg;
|
||||||
|
n_next <= n_reg;
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
ready <= '1';
|
||||||
|
if start='1' then
|
||||||
|
t0_next <= (others=>'0');
|
||||||
|
t1_next <= (0=>'1', others=>'0');
|
||||||
|
n_next <= unsigned(i);
|
||||||
|
state_next <= op;
|
||||||
|
end if;
|
||||||
|
when op =>
|
||||||
|
if n_reg=0 then
|
||||||
|
t1_next <= (others=>'0');
|
||||||
|
state_next <= done;
|
||||||
|
elsif n_reg=1 then
|
||||||
|
state_next <= done;
|
||||||
|
else
|
||||||
|
t1_next <= t1_reg + t0_reg;
|
||||||
|
t0_next <= t1_reg;
|
||||||
|
n_next <= n_reg - 1;
|
||||||
|
end if;
|
||||||
|
when done =>
|
||||||
|
done_tick <= '1';
|
||||||
|
state_next <= idle;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
-- output
|
||||||
|
f <= std_logic_vector(t1_reg);
|
||||||
|
end arch;
|
|
@ -0,0 +1,102 @@
|
||||||
|
-- Listing 6.5
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity div is
|
||||||
|
generic(
|
||||||
|
W: integer:=8;
|
||||||
|
CBIT: integer:=4 -- CBIT=log2(W)+1
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk, reset: in std_logic;
|
||||||
|
start: in std_logic;
|
||||||
|
dvsr, dvnd: in std_logic_vector(W-1 downto 0);
|
||||||
|
ready, done_tick: out std_logic;
|
||||||
|
quo, rmd: out std_logic_vector(W-1 downto 0)
|
||||||
|
);
|
||||||
|
end div;
|
||||||
|
|
||||||
|
architecture arch of div is
|
||||||
|
type state_type is (idle,op,last,done);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal rh_reg, rh_next: unsigned(W-1 downto 0);
|
||||||
|
signal rl_reg, rl_next: std_logic_vector(W-1 downto 0);
|
||||||
|
signal rh_tmp: unsigned(W-1 downto 0);
|
||||||
|
signal d_reg, d_next: unsigned(W-1 downto 0);
|
||||||
|
signal n_reg, n_next: unsigned(CBIT-1 downto 0);
|
||||||
|
signal q_bit: std_logic;
|
||||||
|
begin
|
||||||
|
-- fsmd state and data registers
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= idle;
|
||||||
|
rh_reg <= (others=>'0');
|
||||||
|
rl_reg <= (others=>'0');
|
||||||
|
d_reg <= (others=>'0');
|
||||||
|
n_reg <= (others=>'0');
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
rh_reg <= rh_next;
|
||||||
|
rl_reg <= rl_next;
|
||||||
|
d_reg <= d_next;
|
||||||
|
n_reg <= n_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- fsmd next-state logic and data path logic
|
||||||
|
process(state_reg,n_reg,rh_reg,rl_reg,d_reg,
|
||||||
|
start,dvsr,dvnd,q_bit,rh_tmp,n_next)
|
||||||
|
begin
|
||||||
|
ready <='0';
|
||||||
|
done_tick <= '0';
|
||||||
|
state_next <= state_reg;
|
||||||
|
rh_next <= rh_reg;
|
||||||
|
rl_next <= rl_reg;
|
||||||
|
d_next <= d_reg;
|
||||||
|
n_next <= n_reg;
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
ready <= '1';
|
||||||
|
if start='1' then
|
||||||
|
rh_next <= (others=>'0');
|
||||||
|
rl_next <= dvnd; -- dividend
|
||||||
|
d_next <= unsigned(dvsr); -- divisor
|
||||||
|
n_next <= to_unsigned(W+1, CBIT); -- index
|
||||||
|
state_next <= op;
|
||||||
|
end if;
|
||||||
|
when op =>
|
||||||
|
-- shift rh and rl left
|
||||||
|
rl_next <= rl_reg(W-2 downto 0) & q_bit;
|
||||||
|
rh_next <= rh_tmp(W-2 downto 0) & rl_reg(W-1);
|
||||||
|
--decrease index
|
||||||
|
n_next <= n_reg - 1;
|
||||||
|
if (n_next=1) then
|
||||||
|
state_next <= last;
|
||||||
|
end if;
|
||||||
|
when last => -- last iteration
|
||||||
|
rl_next <= rl_reg(W-2 downto 0) & q_bit;
|
||||||
|
rh_next <= rh_tmp;
|
||||||
|
state_next <= done;
|
||||||
|
when done =>
|
||||||
|
state_next <= idle;
|
||||||
|
done_tick <= '1';
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- compare and subtract
|
||||||
|
process(rh_reg, d_reg)
|
||||||
|
begin
|
||||||
|
if rh_reg >= d_reg then
|
||||||
|
rh_tmp <= rh_reg - d_reg;
|
||||||
|
q_bit <= '1';
|
||||||
|
else
|
||||||
|
rh_tmp <= rh_reg;
|
||||||
|
q_bit <= '0';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- output
|
||||||
|
quo <= rl_reg;
|
||||||
|
rmd <= std_logic_vector(rh_reg);
|
||||||
|
end arch;
|
|
@ -0,0 +1,107 @@
|
||||||
|
-- Listing 6.6
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity bin2bcd is
|
||||||
|
port(
|
||||||
|
clk: in std_logic;
|
||||||
|
reset: in std_logic;
|
||||||
|
start: in std_logic;
|
||||||
|
bin: in std_logic_vector(12 downto 0);
|
||||||
|
ready, done_tick: out std_logic;
|
||||||
|
bcd3,bcd2,bcd1,bcd0: out std_logic_vector(3 downto 0)
|
||||||
|
);
|
||||||
|
end bin2bcd ;
|
||||||
|
|
||||||
|
architecture arch of bin2bcd is
|
||||||
|
type state_type is (idle, op, done);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal p2s_reg, p2s_next: std_logic_vector(12 downto 0);
|
||||||
|
signal n_reg, n_next: unsigned(3 downto 0);
|
||||||
|
signal bcd3_reg,bcd2_reg,bcd1_reg,bcd0_reg: unsigned(3 downto 0);
|
||||||
|
signal bcd3_next,bcd2_next,bcd1_next,bcd0_next: unsigned(3 downto 0);
|
||||||
|
signal bcd3_tmp,bcd2_tmp,bcd1_tmp,bcd0_tmp: unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
-- state and data registers
|
||||||
|
process (clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= idle;
|
||||||
|
p2s_reg <= (others=>'0');
|
||||||
|
n_reg <= (others=>'0');
|
||||||
|
bcd3_reg <= (others=>'0');
|
||||||
|
bcd2_reg <= (others=>'0');
|
||||||
|
bcd1_reg <= (others=>'0');
|
||||||
|
bcd0_reg <= (others=>'0');
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
p2s_reg <= p2s_next;
|
||||||
|
n_reg <= n_next;
|
||||||
|
bcd3_reg <= bcd3_next;
|
||||||
|
bcd2_reg <= bcd2_next;
|
||||||
|
bcd1_reg <= bcd1_next;
|
||||||
|
bcd0_reg <= bcd0_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- fsmd next-state logic / data path operations
|
||||||
|
process(state_reg,start,p2s_reg,n_reg,n_next,bin,
|
||||||
|
bcd0_reg,bcd1_reg,bcd2_reg,bcd3_reg,
|
||||||
|
bcd0_tmp,bcd1_tmp,bcd2_tmp,bcd3_tmp)
|
||||||
|
begin
|
||||||
|
state_next <= state_reg;
|
||||||
|
ready <= '0';
|
||||||
|
done_tick <= '0';
|
||||||
|
p2s_next <= p2s_reg;
|
||||||
|
bcd0_next <= bcd0_reg;
|
||||||
|
bcd1_next <= bcd1_reg;
|
||||||
|
bcd2_next <= bcd2_reg;
|
||||||
|
bcd3_next <= bcd3_reg;
|
||||||
|
n_next <= n_reg;
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
ready <= '1';
|
||||||
|
if start='1' then
|
||||||
|
state_next <= op;
|
||||||
|
bcd3_next <= (others=>'0');
|
||||||
|
bcd2_next <= (others=>'0');
|
||||||
|
bcd1_next <= (others=>'0');
|
||||||
|
bcd0_next <= (others=>'0');
|
||||||
|
n_next <="1101"; -- index
|
||||||
|
p2s_next <= bin; -- input shift register
|
||||||
|
state_next <= op;
|
||||||
|
end if;
|
||||||
|
when op =>
|
||||||
|
-- shift in binary bit
|
||||||
|
p2s_next <= p2s_reg(11 downto 0) & '0';
|
||||||
|
-- shift 4 BCD digits
|
||||||
|
bcd0_next <= bcd0_tmp(2 downto 0) & p2s_reg(12);
|
||||||
|
bcd1_next <= bcd1_tmp(2 downto 0) & bcd0_tmp(3);
|
||||||
|
bcd2_next <= bcd2_tmp(2 downto 0) & bcd1_tmp(3);
|
||||||
|
bcd3_next <= bcd3_tmp(2 downto 0) & bcd2_tmp(3);
|
||||||
|
n_next <= n_reg - 1;
|
||||||
|
if (n_next=0) then
|
||||||
|
state_next <= done;
|
||||||
|
end if;
|
||||||
|
when done =>
|
||||||
|
state_next <= idle;
|
||||||
|
done_tick <= '1';
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- data path function units
|
||||||
|
bcd0_tmp <= bcd0_reg + 3 when bcd0_reg > 4 else
|
||||||
|
bcd0_reg;
|
||||||
|
bcd1_tmp <= bcd1_reg + 3 when bcd1_reg > 4 else
|
||||||
|
bcd1_reg;
|
||||||
|
bcd2_tmp <= bcd2_reg + 3 when bcd2_reg > 4 else
|
||||||
|
bcd2_reg;
|
||||||
|
bcd3_tmp <= bcd3_reg + 3 when bcd3_reg > 4 else
|
||||||
|
bcd3_reg;
|
||||||
|
|
||||||
|
-- output
|
||||||
|
bcd0 <= std_logic_vector(bcd0_reg);
|
||||||
|
bcd1 <= std_logic_vector(bcd1_reg);
|
||||||
|
bcd2 <= std_logic_vector(bcd2_reg);
|
||||||
|
bcd3 <= std_logic_vector(bcd3_reg);
|
||||||
|
end arch;
|
|
@ -0,0 +1,77 @@
|
||||||
|
-- Listing 6.7
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity period_counter is
|
||||||
|
port(
|
||||||
|
clk, reset: in std_logic;
|
||||||
|
start, si: in std_logic;
|
||||||
|
ready, done_tick: out std_logic;
|
||||||
|
prd: out std_logic_vector(9 downto 0)
|
||||||
|
);
|
||||||
|
end period_counter;
|
||||||
|
|
||||||
|
architecture arch of period_counter is
|
||||||
|
constant CLK_MS_COUNT: integer := 5; -- 50000; -- 1 ms tick
|
||||||
|
type state_type is (idle, waite, count, done);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal t_reg, t_next: unsigned(15 downto 0); -- up to 50000
|
||||||
|
signal p_reg, p_next: unsigned(9 downto 0); -- up to 1 sec
|
||||||
|
signal delay_reg: std_logic;
|
||||||
|
signal edge: std_logic;
|
||||||
|
begin
|
||||||
|
-- state and data register
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= idle;
|
||||||
|
t_reg <= (others=>'0');
|
||||||
|
p_reg <= (others=>'0');
|
||||||
|
delay_reg <= '0';
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
t_reg <= t_next;
|
||||||
|
p_reg <= p_next;
|
||||||
|
delay_reg <= si;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
edge <= (not delay_reg) and si;
|
||||||
|
|
||||||
|
process(start,edge,state_reg,t_reg,t_next,p_reg)
|
||||||
|
begin
|
||||||
|
ready <= '0';
|
||||||
|
done_tick <= '0';
|
||||||
|
state_next <= state_reg;
|
||||||
|
p_next <= p_reg;
|
||||||
|
t_next <= t_reg;
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
ready <= '1';
|
||||||
|
if (start='1') then
|
||||||
|
state_next <= waite;
|
||||||
|
end if;
|
||||||
|
when waite => -- wait for the first edge
|
||||||
|
if (edge='1') then
|
||||||
|
state_next <= count;
|
||||||
|
t_next <= (others=>'0');
|
||||||
|
p_next <= (others=>'0');
|
||||||
|
end if;
|
||||||
|
when count =>
|
||||||
|
if (edge='1') then -- 2nd edge arrived
|
||||||
|
state_next <= done;
|
||||||
|
else -- otherwise count
|
||||||
|
if t_reg = CLK_MS_COUNT-1 then -- 1ms tick
|
||||||
|
t_next <= (others=>'0');
|
||||||
|
p_next <= p_reg + 1;
|
||||||
|
else
|
||||||
|
t_next <= t_reg + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when done =>
|
||||||
|
done_tick <= '1';
|
||||||
|
state_next <= idle;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
prd <= std_logic_vector(p_reg);
|
||||||
|
end arch;
|
|
@ -0,0 +1,87 @@
|
||||||
|
-- Listing 6.8
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity low_freq_counter is
|
||||||
|
port(
|
||||||
|
clk, reset: in std_logic;
|
||||||
|
start: in std_logic;
|
||||||
|
si: in std_logic;
|
||||||
|
bcd3, bcd2, bcd1, bcd0: out std_logic_vector(3 downto 0)
|
||||||
|
);
|
||||||
|
end low_freq_counter;
|
||||||
|
|
||||||
|
architecture arch of low_freq_counter is
|
||||||
|
type state_type is (idle, count, frq, b2b);
|
||||||
|
signal state_reg, state_next: state_type;
|
||||||
|
signal prd: std_logic_vector(9 downto 0);
|
||||||
|
signal dvsr, dvnd, quo: std_logic_vector(19 downto 0);
|
||||||
|
signal prd_start, div_start, b2b_start: std_logic;
|
||||||
|
signal prd_done_tick, div_done_tick, b2b_done_tick: std_logic;
|
||||||
|
begin
|
||||||
|
--===============================================
|
||||||
|
-- component instantiation
|
||||||
|
--===============================================
|
||||||
|
-- instantiate period counter
|
||||||
|
prd_count_unit: entity work.period_counter
|
||||||
|
port map(clk=>clk, reset=>reset, start=>prd_start, si=>si,
|
||||||
|
ready=>open, done_tick=>prd_done_tick, prd=>prd);
|
||||||
|
-- instantiate division circuit
|
||||||
|
div_unit: entity work.div
|
||||||
|
generic map(W=>20, CBIT=>5)
|
||||||
|
port map(clk=>clk, reset=>reset, start=>div_start,
|
||||||
|
dvsr=>dvsr, dvnd=>dvnd, quo=>quo, rmd=>open,
|
||||||
|
ready=>open, done_tick=>div_done_tick);
|
||||||
|
-- instantiate binary-to-BCD convertor
|
||||||
|
bin2bcd_unit: entity work.bin2bcd
|
||||||
|
port map
|
||||||
|
(clk=>clk, reset=>reset, start=>b2b_start,
|
||||||
|
bin=>quo(12 downto 0), ready=>open,
|
||||||
|
done_tick=>b2b_done_tick,
|
||||||
|
bcd3=>bcd3, bcd2=>bcd2, bcd1=>bcd1, bcd0=>bcd0);
|
||||||
|
-- signal width extension
|
||||||
|
dvnd <= std_logic_vector(to_unsigned(1000000, 20));
|
||||||
|
dvsr <= "0000000000" & prd;
|
||||||
|
|
||||||
|
--===============================================
|
||||||
|
-- Master FSM
|
||||||
|
--===============================================
|
||||||
|
process(clk,reset)
|
||||||
|
begin
|
||||||
|
if reset='1' then
|
||||||
|
state_reg <= idle;
|
||||||
|
elsif (clk'event and clk='1') then
|
||||||
|
state_reg <= state_next;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(state_reg,start,
|
||||||
|
prd_done_tick,div_done_tick,b2b_done_tick)
|
||||||
|
begin
|
||||||
|
state_next <= state_reg;
|
||||||
|
prd_start <='0';
|
||||||
|
div_start <='0';
|
||||||
|
b2b_start <='0';
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
if start='1' then
|
||||||
|
state_next <= count;
|
||||||
|
prd_start <='1';
|
||||||
|
end if;
|
||||||
|
when count =>
|
||||||
|
if (prd_done_tick='1') then
|
||||||
|
div_start <='1';
|
||||||
|
state_next <= frq;
|
||||||
|
end if;
|
||||||
|
when frq =>
|
||||||
|
if (div_done_tick='1') then
|
||||||
|
b2b_start <='1';
|
||||||
|
state_next <= b2b;
|
||||||
|
end if;
|
||||||
|
when b2b =>
|
||||||
|
if (b2b_done_tick='1') then
|
||||||
|
state_next <= idle;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
end arch;
|
|
@ -0,0 +1,12 @@
|
||||||
|
SET speed=2
|
||||||
|
SET ruta_ucf=ch06
|
||||||
|
SET ruta_bat=..\..\
|
||||||
|
call :genbitstream debounce_test
|
||||||
|
goto :eof
|
||||||
|
|
||||||
|
:genbitstream
|
||||||
|
SET machine=%1
|
||||||
|
call %ruta_bat%genxst.bat
|
||||||
|
call %ruta_bat%generar.bat v4 ZX1
|
||||||
|
copy /y COREn.ZX1 %ruta_ucf%_%machine%.ZX1
|
||||||
|
goto :eof
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Timing constraints
|
||||||
|
NET "clk" PERIOD=20 ns;
|
Loading…
Reference in New Issue