📄 dual2bcd.vhd
字号:
--------------------------------------------------------------------------------- Title : DUAL to BCD conversion module-- Project : --------------------------------------------------------------------------------- File : dual2bcd.vhd-- Author : Richard Geissler <richard.geissler@e-technik.uni-ulm.de>-- Company : University of Ulm-- Last update: 2005/11/29-- Platform : --------------------------------------------------------------------------------- Description: sequential conversion of a dual number representation to a-- BCD representation. The dual number is captured synchronous to-- a rising CLK edge from the port DUAL when START='1'. The START-- signal should be '1' only during the capturing CLK edge. The-- result BCD is valid at the next rising CLK edge when READY='1'.-- The module is scaled by the three generics DUALBITS (the number-- of bits of the dual number), BCDBITS (the number of bits-- required for the BCD representation) and BCDBLKS (the number of-- BCD-blocks in the BCD representation which is equal to-- BCDBITS/4). --------------------------------------------------------------------------------- Revisions :-- Date Version Author Description-- 2000/02/25 1.0 rgeissle Created-- 2000/11/17 1.1 rgeissle improved reset behavior-- 2000/01/19 1.2 rgeissle now all register use async RESET-- 2005/11/29 wschleck now all register use sync RESET (Warnings in postsim ISE 7.1)-- 2007/11/14 cbeusche use library numeric_std instead of std_logic_arith-------------------------------------------------------------------------------LIBRARY ieee;USE ieee.std_logic_1164.all;USE ieee.numeric_std.all;ENTITY dual2bcd IS generic ( DUALBITS : natural := 14; BCDBITS : natural := 16; BCDBLKS : natural := 4); port ( RESET : in std_logic; CLK : in std_logic; START : in std_logic; DUAL : in std_logic_vector(DUALBITS-1 downto 0); BCD : out std_logic_vector(BCDBITS-1 downto 0); READY : out std_logic);END dual2bcd ;-- hds interface_endARCHITECTURE behavioral_dual2bcd OF dual2bcd IS signal DUALREG : std_logic_vector(DUALBITS-1 downto 0); signal BCDREG, CORRECT : std_logic_vector(BCDBITS-1 downto 0); signal LOADDUAL, LOADBCD, RESETBCD, SHIFT_ENA : std_logic; -- F黵 die Steuerung type T_STATE is (SHIFT, CAP, KORREKT); signal STATE, NEXT_STATE : T_STATE; signal READY_INT, CNT : std_logic; signal CNT_STATE, CNT_NEXT_STATE : natural range 0 to DUALBITS-1; -- Das folgende Attribut bringt leider nicht den gew黱schten Erfolg -- attribute sync_set_reset of START : signal is "true";begin -- BEHAVIORAL DREGPROC : process (CLK) begin -- process if CLK'event and CLK = '1' then -- rising clock edge if RESET = '1' then DUALREG <= (others => '0'); elsif LOADDUAL='1' then -- synchronous load from port DUAL DUALREG <= DUAL; elsif SHIFT_ENA='1' then -- shiftregister DUALREG <= DUALREG(DUALBITS-2 downto 0) & '0'; end if; end if; end process; BCDREGPROC : process (CLK) begin -- process if CLK'event and CLK = '1' then -- rising clock edge if RESET = '1' or RESETBCD='1' then BCDREG <= (others => '0'); -- synchronous reset elsif LOADBCD='1' then -- synchronous load from correcting logic BCDREG <= CORRECT; elsif SHIFT_ENA='1' then -- shiftregister BCDREG <= BCDREG(BCDBITS-2 downto 0) & DUALREG(DUALBITS-1); end if; end if; end process; CORRECTPROC: process (BCDREG) variable CORRECTION : unsigned(BCDBITS-1 downto 0); begin -- process CORRECTPROC CORRECTION := (others => '0'); for i in 1 to BCDBLKS loop if unsigned(BCDREG(4*i-1 downto 4*(i-1))) >= 5 then CORRECTION(4*i-3 downto 4*(i-1)) := "11"; end if; end loop; -- i CORRECT <= std_logic_vector(unsigned(BCDREG) + CORRECTION); end process CORRECTPROC; BCD <= BCDREG; LOADDUAL <= START; RESETBCD <= START; READYDELAY: process (CLK) begin -- process READYDELAY if CLK'event and CLK = '1' then -- rising clock edge if RESET = '1' then READY <= '0'; else READY <= READY_INT; end if; end if; end process READYDELAY; -- Controller for sequentially coding DUAL -> BCD -- consisting of two FSM: -- 1) control of capturing, shifting and correction -- 2) counter for number of shift operations -- control of capturing, shifting and correction CONTROLMEM: process (CLK) begin -- process CONTROLMEM if CLK'event and CLK = '1' then -- rising clock edge if RESET = '1' then STATE <= CAP; elsif START='1' then STATE <= SHIFT; else STATE <= NEXT_STATE; end if; end if; end process CONTROLMEM; CONTROLLOGIC: process (STATE, START, READY_INT) variable SR : std_logic_vector(1 downto 0); begin -- process CONTROLLOGIC SR := START & READY_INT; case STATE is when CAP => CNT <= '0'; LOADBCD <= '0'; SHIFT_ENA <= '0'; case SR is when "10" => NEXT_STATE <= SHIFT; when others => NEXT_STATE <= CAP; end case; when SHIFT => CNT <= '0'; LOADBCD <= '0'; SHIFT_ENA <= '1'; case SR is when "00" => NEXT_STATE <= KORREKT; when "01" => NEXT_STATE <= CAP; when others => NEXT_STATE <= SHIFT; end case; when KORREKT => CNT <= '1'; LOADBCD <= '1'; SHIFT_ENA <= '0'; case SR is when "00" => NEXT_STATE <= SHIFT; when others => NEXT_STATE <= KORREKT; end case; end case; end process CONTROLLOGIC; -- counter for number of shift operations CNTMEM: process (CLK) begin -- process CNTMEM if CLK'event and CLK = '1' then -- rising clock edge if RESET = '1' or START='1' then CNT_STATE <= 0; else CNT_STATE <= CNT_NEXT_STATE; end if; end if; end process CNTMEM; CNTLOGIC: process (CNT, CNT_STATE) begin -- process CNTLOGIC if CNT_STATE >= DUALBITS-1 then READY_INT <= '1'; if CNT='1' then CNT_NEXT_STATE <= CNT_STATE; else CNT_NEXT_STATE <= 0; end if; else READY_INT <= '0'; if CNT='1' then CNT_NEXT_STATE <= CNT_STATE+1; else CNT_NEXT_STATE <= CNT_STATE; end if; end if; end process CNTLOGIC; END behavioral_dual2bcd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -