OpenCores
URL https://opencores.org/ocsvn/signed_unsigned_multiplier_and_divider/signed_unsigned_multiplier_and_divider/trunk

Subversion Repositories signed_unsigned_multiplier_and_divider

[/] [signed_unsigned_multiplier_and_divider/] [trunk/] [bin2bcd.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    18:02:11 03/25/2018 
-- Design Name: 
-- Module Name:    bin2bcd - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
 
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity bin2bcd is
    Port ( reset : in  STD_LOGIC;		-- Initialize when high, note that it will drive ready low
           clk : in  STD_LOGIC;			-- Drives the FSM
           start : in  STD_LOGIC;		-- Keep high for at least 1 clock cycle to start conversion
           bin : in  STD_LOGIC_VECTOR (15 downto 0);		-- 16-bit unsigned binary input value
			  ready : out  STD_LOGIC;		-- pulse high when conversion is done
           bcd : buffer STD_LOGIC_VECTOR (23 downto 0);	-- 6 BCD digits output
			  debug: out STD_LOGIC_VECTOR(3 downto 0));		-- debug port, leave open
end bin2bcd;
 
architecture Behavioral of bin2bcd is
 
component bcddigitadder is
    Port ( ci : in  STD_LOGIC;
           a : in  STD_LOGIC_VECTOR (3 downto 0);
           b : in  STD_LOGIC_VECTOR (3 downto 0);
           y : out  STD_LOGIC_VECTOR (3 downto 0);
           cout : out  STD_LOGIC);
end component;
 
type state is (st_reset, st_readytostart, st_loadbinval, st_checkzero,
					st_delay, st_update,
					st_shiftdown, st_done);
 
type rom24x16 is array(0 to 15) of std_logic_vector(23 downto 0);
constant bcd_lookup: rom24x16 := (
	0 => 	X"000001",
	1 =>	X"000002",
	2 =>	X"000004",
	3 =>	X"000008",
	4 =>	X"000016",
	5 =>	X"000032",
	6 =>	X"000064",
	7 =>	X"000128",
	8 =>	X"000256",
	9 =>	X"000512",
	10 =>	X"001024",
	11 => X"002048",
	12 =>	X"004096",
	13 =>	X"008192",
	14 =>	X"016384",
	15 =>	X"032768"
);
 
signal state_current, state_next: state;
 
signal power: integer range 0 to 15;	-- index to bcd lookup table (2^power in bcd format)
signal zero: std_logic;
signal ripple_carry: std_logic_vector(6 downto 0);
signal bin_val: std_logic_vector(15 downto 0);
signal power_val: std_logic_vector(23 downto 0);
signal bcd_plus_power: std_logic_vector(23 downto 0);
 
begin
 
debug <= std_logic_vector(to_unsigned(power, 4));
 
power_val <= bcd_lookup(power);
ripple_carry(0) <= '0';
zero <= '1' when bin_val = X"0000" else '0';
 
gen_digit_adders: for i in 0 to 5 generate -- six output digits
	digadd: bcddigitadder port map 
				(
					ci => ripple_carry(i),
					a => bcd(3 + 4 * i downto 4 * i),
					b => power_val(3 + 4 * i downto 4 * i),
					y => bcd_plus_power(3 + 4 * i downto 4 * i),
					cout => ripple_carry(i + 1)
				);
end generate;
 
-- FSM
drive: process(reset, clk, state_next)
begin
	if (reset = '1') then
		state_current <= st_reset;
	else
		if (rising_edge(clk)) then
			state_current <= state_next;
		end if;
	end if;
end process;
 
execute: process(clk, state_current)
begin
	if (rising_edge(clk)) then
		case state_current is
			when st_reset =>
				ready <= '0';
 
			when st_readytostart =>
				ready <= '1';
				power <= 0;
 
			when st_loadbinval =>
				ready <= '0';
				bin_val <= bin;
				bcd <= X"000000";
 
			when st_checkzero =>
 
			when st_delay =>
 
			when st_update =>
				bcd <= bcd_plus_power;
 
			when st_shiftdown =>
				bin_val <= '0' & bin_val(15 downto 1);
				power <= power + 1;
 
			when st_done =>
				ready <= '1';
 
			when others =>
				null;
 
		end case;
	end if;
end process;
 
sequence: process(state_current, zero, bin_val) 
begin
	case state_current is
		when st_reset =>
			state_next <= st_readytostart;
 
		when st_readytostart =>
			if (start = '1') then
				state_next <= st_loadbinval; 
			else
				state_next <= st_readytostart; -- continue waiting for start
			end if;
 
		when st_loadbinval =>
			state_next <= st_checkzero;
 
		when st_checkzero =>
			if (zero = '1') then
				state_next <= st_done;
			else
				if (bin_val(0) = '1') then
					state_next <= st_delay;
				else
					state_next <= st_shiftdown;
				end if;
			end if;
 
		when st_delay =>
			state_next <= st_update;
 
		when st_update =>
			state_next <= st_shiftdown;
 
		when st_shiftdown =>
			state_next <= st_checkzero;
 
		when st_done =>
			state_next <= st_readytostart;
 
		when others =>
			null;
	end case;
end process;
 
 
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.