⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdl.txt

📁 加法器 乘法器电路 除法器电路设计 键盘扫描电路设计 显示电路
💻 TXT
📖 第 1 页 / 共 2 页
字号:
		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 + -