📄 vhdl.txt
字号:
ea <= '1' ; eb <= '1' ; psel <= '1' ;
if b(0) = '1' then ep <= '1' ; else ep <= '0' ; end if ;
when s3 =>
done <= '1' ;
end case ;
end process ;
-- define the datapath circuit
nn_zeros <= (others => '0' ) ;--2*n-bit zero
n_zeros <= (others => '0' ) ;--n-bit zero
zero <= '0' ;
ain <= n_zeros & dataa ;
shifta: shiftlne generic map ( n => nn )
port map ( ain, la, ea, zero, clock, a ) ;
shiftb: shiftrne generic map ( n => n )
port map ( datab, lb, eb, zero, clock, b ) ;
ec <= '1' ; lc <= not s;
count: downcnt generic map (n+1) port map(clock,ec,lc,q);
z <= '1' when q = 0 else '0' ;
sum <= a + p ;
-- define the 2n 2-to-1 multiplexers for datap
muxi: mux2to1 generic map ( n => nn )
port map ( nn_zeros, sum, psel, datap ) ;
regp: regne generic map ( n => nn )
port map ( datap, ep, clock, p ) ;
end behavior ;
5-3 除法器电路设计
--divider.vhd n-bit divider
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all ;
use work.components.all ;
entity divider is
generic ( n : integer := 7 ) ;
port (
clock : in std_logic ;--clock
s : in std_logic ;--start operation
la : in std_logic ;--load of dividend
eb: in std_logic ;--enable(load) of divisor
dataa : in std_logic_vector(n-1 downto 0) ;--dividend
datab : in std_logic_vector(n-1 downto 0) ;--divisor
r : buffer std_logic_vector(n-1 downto 0) ;--remainder
q : buffer std_logic_vector(n-1 downto 0) ;--quotient
done : out std_logic ) ;--done operation
end divider ;
architecture behavior of divider is
type state_type is ( s1, s2, s3 ) ;--state declaration
signal y : state_type ;--state definition
signal zero : std_logic ;--one bit zero
signal cout : std_logic ;--subtractor carry-out
signal z : std_logic ;--detecter of zero
signal ea : std_logic ;--enable of dividend
signal rsel : std_logic ;--selected line of register r's multiplexer
signal lr : std_logic ;--load of quotient
signal er : std_logic ;--enable of quotient
signal er0: std_logic ;--enable of rr0 register
signal lc : std_logic ;--load of downcounter
signal ec : std_logic ;--enable of downcounter
signal r0 : std_logic ;--output of register a's multiplexer
signal a : std_logic_vector(n-1 downto 0) ;--output of register a(dividend)
signal b : std_logic_vector(n-1 downto 0) ;--output of register b(divisor)
signal datar : std_logic_vector(n-1 downto 0) ;--parallel load of register r(remainder)
signal sum : std_logic_vector(n downto 0) ;--sum of subtractor
signal count : integer range 0 to n-1 ;--range of downcounter
begin
fsm_transitions: process ( clock )
begin
if (clock'event and clock = '1') then
case y is
when s1 =>
if s = '0' then y <= s1 ; else y <= s2 ; end if ;
when s2 =>
if z = '0' then y <= s2 ; else y <= s3 ; end if ;
when s3 =>
if s = '1' then y <= s3 ; else y <= s1 ; end if ;
end case ;
end if ;
end process ;
fsm_outputs: process ( s, y, cout, z )
begin
lr <= '0' ; er <= '0' ; er0 <= '0' ;--initialize value
ea <= '0' ; done <= '0' ;
rsel <= '0' ;
case y is
when s1 =>
er <= '1' ;
if s = '0' then
lr <= '1' ;
if la = '1' then ea <= '1' ; else ea <= '0' ; end if ;
else
ea <= '1' ; er0 <= '1' ;
end if ;
when s2 =>
rsel <= '1' ; er <= '1' ; er0 <= '1' ; ea <= '1' ;
if cout = '1' then lr <= '1' ; else lr <= '0' ; end if ;
when s3 =>
done <= '1' ;
end case ;
end process ;
-- define the datapath circuit
zero <= '0' ;
--divisor
regb: regne generic map ( n => n )
port map ( datab, eb, clock, b ) ;
--remainder
shiftr: shiftlne generic map ( n => n )
port map ( datar, lr, er, r0, clock, r ) ;
--flip-flop with multiplexer
ff_r0: muxdff port map ( zero, a(n-1), er0, clock, r0 ) ;
--dividend
shifta: shiftlne generic map ( n => n )
port map ( dataa, la, ea, cout, clock, a ) ;
q <= a ;
--downcounter
ec <= '1' ; lc <= not s;
counter: downcnt generic map ( modulus => n+1 )
port map ( clock, ec, lc, count ) ;
--nor gate zero detector
z <= '1' when count = 0 else '0' ;
--subtractor
sum <= r & r0 + (not b +1) ;
cout <= sum(n) ;
--multiplexer of register r(remainder)
datar <= (others => '0') when rsel = '0' else sum(n-1 downto 0) ;
end behavior ;
5-4 键盘扫描电路设计
5-4-1 除频器电路
-scan_gen.vhd keyboard scan_clock generator
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity scan_gen is
generic (osc_f : integer := 3686 ; osc_bit : integer := 12);
--generic (osc_f : integer := 100 ; osc_bit : integer := 7); for testing
port(
clk : in std_logic;--clock
scan_f : out std_logic);--1khz
end scan_gen;
architecture behavior of scan_gen is
begin
scan_freq:process(clk)
variable qscan : std_logic_vector(osc_bit-1 downto 0);
begin
if(clk'event and clk='1')then
if (qscan>=osc_f-1) then
for i in osc_bit-1 downto 0 loop
qscan(i):='0';--reset to zero
end loop;
else
qscan:=qscan+1;
end if;
end if;
if (qscan>=osc_f-1) then
scan_f<='1';--count to osc_f then generate pulse
else
scan_f<='0';--remain zero
end if;
end process scan_freq;
end behavior;
键盘扫描计数器电路
--scan_count.vhd scan keypress counter
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity scan_count is
port(
clk : in std_logic;--clock
scan_f : in std_logic;--1khz clock
key_pressed : in std_logic;--detect key_preeed to stop counter
scan_cnt : out std_logic_vector(3 downto 0));--count
end scan_count;
architecture behavior of scan_count is
signal qscan : std_logic_vector(3 downto 0);
begin
scan_1:process(clk,scan_f,key_pressed)
begin
if (clk'event and clk='1') then
if(scan_f='1' and key_pressed='1') then
qscan<=qscan+1;
end if;
end if;
end process;
scan_cnt<=qscan;
end behavior;
按键侦测电路
--key_scan.vhd keypress scaner
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.components.all;
entity key_scan is
port(
col : in std_logic_vector(3 downto 0);--keybord column state
scan_cnt : in std_logic_vector(3 downto 0);--keybord scan location
row : out std_logic_vector(3 downto 0);--keybord row state
key_pressed : out std_logic);--key_pressed->0 unkey_pressed->1
end key_scan;
architecture behavior of key_scan is
begin
row<="1110" when scan_cnt(3 downto 2)="00" else--row scan
"1101" when scan_cnt(3 downto 2)="01" else
"1011" when scan_cnt(3 downto 2)="10" else
"0111";
key_pressed<=col(0) when scan_cnt(1 downto 0)="00" else--colum scan
col(1) when scan_cnt(1 downto 0)="01" else
col(2) when scan_cnt(1 downto 0)="10" else
col(3);
end behavior;
按键反弹跳电路
--debounce.vhd keypress debounce
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debounce is
port(
key_pressed : in std_logic;--key_pressed?
clk : in std_logic;--clock for synchrony
scan_f : in std_logic;--1khz clock
key_valid : out std_logic);--key_valid?
end debounce;
architecture behavior of debounce is
begin
debounce:process(clk,scan_f,key_pressed)
variable dbnq : std_logic_vector(5 downto 0);
begin
if (key_pressed='1') then
dbnq:="111111";--unkey_pressed,counter reset at 63
elsif (clk'event and clk='1') then
if scan_f='1' then
if dbnq/=1 then
dbnq:=dbnq-1;--key_pressed not enough long time
end if; --counter still subtract one
end if;
end if;
if dbnq=2 then
key_valid<='1';--key_valid after key_pressed 1/63k second
else
key_valid<='0';--key_invalid
end if;
end process;
end behavior;
键盘编码电路
--code_tran.vhd keyboard position to button code transformer
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity code_tran is
port(
scan_cnt : in std_logic_vector(3 downto 0) ;--keybord scan count
clk : in std_logic ;--clock
butt_code : out std_logic_vector(3 downto 0)) ;--button code
end code_tran ;
architecture behavior of code_tran is
begin
code_tran:process(clk)
begin
if(clk'event and clk='1') then
case scan_cnt is --encoding
when "0000"=> butt_code <= "0001";--1
when "0001"=> butt_code <= "0010";--2
when "0010"=> butt_code <= "0011";--3
when "0011"=> butt_code <= "1100";--c
when "0100"=> butt_code <= "0100";--4
when "0101"=> butt_code <= "0101";--5
when "0110"=> butt_code <= "0110";--6
when "0111"=> butt_code <= "1101";--d
when "1000"=> butt_code <= "0111";--7
when "1001"=> butt_code <= "1000";--8
when "1010"=> butt_code <= "1001";--9
when "1011"=> butt_code <= "1110";--e
when "1100"=> butt_code <= "1010";--a
when "1101"=> butt_code <= "0000";--0
when "1110"=> butt_code <= "1011";--b
when others => butt_code <= "1111";--f
end case;
end if;
end process;
end behavior;
键盘扫描电路
--keyboard.vhd keyboard scanner
library ieee ;
use ieee.std_logic_1164.all;
use work.components.all ;
entity keyboard is
port(
clock : in std_logic ;
col : in std_logic_vector(3 downto 0 ) ;
row : out std_logic_vector(3 downto 0) ;
scan_f : out std_logic ;
key_valid : out std_logic ;
butt_code : out std_logic_vector(3 downto 0)) ;
end keyboard;
architecture behavior of keyboard is
signal scanf : std_logic ;
signal key_pressed : std_logic ;
signal scan_cnt : std_logic_vector(3 downto 0) ;
begin
divfreq: scan_gen
generic map ( osc_f => 3686 , osc_bit => 12 )
port map ( clock, scanf ) ;
keycount: scan_count
port map ( clock, scanf, key_pressed, scan_cnt ) ;
keyscan: key_scan
port map ( col, scan_cnt, row, key_pressed ) ;
debounkey: debounce
port map ( key_pressed, clock, scanf, key_valid ) ;
coding: code_tran
port map ( scan_cnt, clock, butt_code ) ;
scan_f <= scanf ;
end behavior;
显示电路
七段显示器扫描电路
--comcoun.vhd 7 segment com scan counter
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity comcoun is
port(
clk : in std_logic;--synchronouse clock
f1k_ena : in std_logic;--scan clock
comclk : out std_logic_vector(1 downto 0));--output count
end comcoun;
architecture behavior of comcoun is
signal q : std_logic_vector(1 downto 0);--internal counted signal
begin
fscan:process(clk)
begin
if (clk'event and clk='1') then
if (f1k_ena='1') then
if q>=3 then
q<="00";--initial counter
else
q<=q+1;--counting
end if;
end if;
end if;
end process fscan;
comclk<=q;--output internal count
end behavior;
计数译码电路
--com_encode.vhd 7 segment com encoder
library ieee ;
use ieee.std_logic_1164.all;
entity com_encode is
port(
com_clk : in std_logic_vector(1 downto 0);--input count
ledcom : out std_logic_vector(3 downto 0));--output encode
end com_encode;
architecture behavior of com_encode is
begin
ledcom<="1110" when com_clk="00" else
"1101" when com_clk="01" else
"1011" when com_clk="10" else
"0111";
end behavior;
bcd选择多任务器
--bcd_mux.vhd multiplexer of bcd-selection
library ieee ;
use ieee.std_logic_1164.all;
entity bcd_mux is
port(
com_clk : in std_logic_vector(1 downto 0);--input count
bcd_data : in std_logic_vector(15 downto 0);--input display data
bcd_led : out std_logic_vector(3 downto 0));--output to 7 segment
end bcd_mux;
architecture behavior of bcd_mux is
begin
bcd_led<=bcd_data(3 downto 0) when com_clk="00" else
bcd_data(7 downto 4) when com_clk="01" else
bcd_data(11 downto 8) when com_clk="10" else
bcd_data(15 downto 12);
end behavior;
bcd对应七段显示器编码电路
--bcd_7seg.vhd bcd to 7 segment encoder
library ieee ;
use ieee.std_logic_1164.all;
entity bcd_7seg is
port(
bcd_led : in std_logic_vector(3 downto 0);--input bcd
ledseg : out std_logic_vector(6 downto 0));--output to 7 segment
end bcd_7seg;
architecture behavior of bcd_7seg is
begin
with bcd_led select
ledseg<="0111111" when "0000",--0
"0000110" when "0001",--1
"1011011" when "0010",--2
"1001111" when "0011",--3
"1100110" when "0100",--4
"1101101" when "0101",--5
"1111101" when "0110",--6
"0100111" when "0111",--7
"1111111" when "1000",--8
"1101111" when "1001",--9
"1000000" when "1110",--minus
"0000000" when others;
end behavior;
显示电路整合
--ledscan.vhd 4 digit bcd-to-7 segment scan display
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.components.all;
entity ledscan is
port(
clk : in std_logic;--synchronous
f1k_ena : in std_logic;--scan clock
bcd_data : in std_logic_vector(15 downto 0);--input bcd
ledseg : out std_logic_vector(6 downto 0);--output to 7 segment
ledcom : out std_logic_vector(3 downto 0));--7 segment enable
end ledscan;
architecture behavior of ledscan is
signal com_clk : std_logic_vector(1 downto 0);
signal bcd_led : std_logic_vector(3 downto 0);
begin
u0: comcoun port map (clk,f1k_ena,com_clk);-- 7 segment com scan counter
u1: com_encode port map (com_clk,ledcom);--7 segment com encode
u2: bcd_mux port map (com_clk,bcd_data,bcd_led);--multiplexer
u3: bcd_7seg port map (bcd_led,ledseg);--bcd to 7 segment encoder
end behavior;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -