哪位大神能用vhdl语言实现16位2进制数转换成10进制数啊 就是输出一个10进制整数....真是怎么弄不对啊 谢谢
3个回答
展开全部
可以参考 xilinx 的 application note "Serial Code Conversion between
BCD and Binary"
http://www.ingelec.uns.edu.ar/dclac2558/BCD2BIN.PDF
The basic idea is to shift data serially into a shift register. As each bit is shifted in, the accumulated sum is collected. Each shift effectively doubles the value of the binary number in the four bit shift register which is going to hold the converted BCD digit.
Each time a bit is shifted in, the value in the shift register is doubled. After four bits have been shifted in, if the original value is 0, 1, 2, 3, or 4, then the result is within the 0-9 range of a BCD digit and there is no action required.
If the value is 5, 6, 7, 8, or 9, then the doubled result is greater than 10, so a carry out (called ModOut in the code) is generated to represent the overflow into the tens column (i.e. into the next BCD digit). Here's a little table showing how to double each bit in BCD. All numbers shown are decimal.
input tens units result
0 0 0 0
1 0 2 2
2 0 4 4
3 0 6 6
4 0 8 8
5 1 0 10
6 1 2 12
7 1 4 14
8 1 6 16
9 1 8 18
The tens column thus represents an overflow into the next most significant BCD digit.
Does this all seems a bit baffling? There's a more thorough explanation in the application note referenced above.
The code is in three files:
digit.vhd
This contains a model for one four bit BCD digit, with carry in (ModIn) and carry out (ModOut). The digit has asynchronous reset, and an Init signal. The Init signal forces the carry out to zero at before a conversion starts.
bcdconv.vhd
This contains a generic N which allows you to specify the number of 4 bit BCD digits in the BCD converter. The generic is used to control a generate statement, which makes N instances of the Digit component described above.
bcdconvtb.vhd
This contains a testbench which applies a serial binary input representing a range of binary numbers, and then writes out the corresponding BCD equivalents
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use STD.textio.all;
entity BCDConvTB is
end;
architecture Bench of BCDConvTB is
component BCDConv
generic (N : positive);
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic;
ModIn : in std_logic;
ModOut : out std_logic;
Q : out std_logic_vector(N*4-1 downto 0)
);
end component;
-- hold an array of BCD digits
type BCDVectorT is array (natural range <>) of std_logic_vector(3 downto 0);
-- number of digits implemented in this test bench
constant N : positive := 5;
-- BCD array as a single std_logic_vector (packed in 4 bits at a
-- time)
subtype BcdT is std_logic_vector(N*4-1 downto 0);
signal Clock : std_logic;
signal Reset : std_logic;
signal Init : std_logic; -- Initialise BCD conversion
signal ModIn : std_logic; -- modulus in, if we wanted to
-- cascade lots of NDigits design entities
signal ModOut : std_logic; -- modulus out, same reason as ModIn
signal Q : BCDT; -- The outputs of the BCD conversion packed
-- into a std_logic_vector
-- Test bench control signal to ensure Clock stops when testing is over
signal StopClock : boolean;
-- Outputs of BCD conversion as an array of 4 bit digits.
signal BCDVec : BcdVectorT(1 to N);
-- Type to allow a table of test values
type TableT is array (natural range <>) of Integer;
-- some interesting values to test
constant Table : TableT := (17,18,19,20,21,22,23,30,40,50,
60,70,80,90,91,92,93,94,95,96,
97,98,99,100,101,302,
555,707,9999,10100, 99999);
signal TestInteger : Integer;
begin
UUT: BCDConv
generic map (N => N)
port map (
Clock => Clock,
Reset => Reset,
Init => Init,
ModIn => ModIn,
ModOut => ModOut,
Q => Q);
-- 100 ns clock. Clock loop stops automatically when the
-- stimulus process has finished, using the boolean signal StopClock
ClockGen: process
begin
while not StopClock loop
Clock <= '0';
wait for 50 ns;
Clock <= '1';
wait for 50 ns;
end loop;
wait;
end process;
--
-- Generate a set of values to test the Binary to BCD converter
--
StimGen: process
variable TestVal : BCDT;
variable L : LINE;
begin
Reset <= '0';
ModIn <= '0';
Init <= '0';
wait until falling_edge(Clock);
Reset <= '1';
wait until falling_edge(Clock);
Reset <= '0';
-- test all the values in the table
write(L, STRING'("Expected:"), LEFT, 10);
write(L, STRING'("Actual:"), LEFT, 10);
writeline(OUTPUT,L);
for I in Table'RANGE loop
-- convert integer value to std_logic_vector
TestVal := std_logic_vector(to_unsigned(Table(I), N*4));
-- assign the test value to an integer signal - easy to
-- disply in the simulator
TestInteger <= Table(I);
write(L, Table(I), LEFT, 10);
-- Loop round all the bits in the input vector
for J in BCDT'RANGE loop
-- initialise conversion if shifting in the first bit
if J = BCDT'LEFT then
Init<= '1';
else
Init <= '0';
end if;
ModIn <= TestVal(J);
wait until falling_edge(Clock);
end loop;
-- pack the result from the converter into a single std_logic_vector
-- (and write them as we go to check against the originals).
for J in 1 to N loop
BCDVec(J) <= Q(J*4-1 downto J*4-4);
write(L, to_integer(unsigned(Q(J*4-1 downto J*4-4))));
end loop;
writeline(OUTPUT,L);
end loop;
StopClock <= TRUE; -- tell the clock generator to stop
wait;
end process;
end;
-- must have a configuration for synopsys vhdl simulator
use work.all;
configuration cfg_BCDConvTB of BCDConvTB is
for Bench
end for;
end;
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity BCDConv is
generic (N : positive); -- number of digits
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic; -- initialise conversion
ModIn : in std_logic; -- carry in from outside
ModOut : out std_logic; -- carry out
Q : out std_logic_vector(4*N -1 downto 0) -- BCD result
);
end;
architecture RTL of BCDConv is
component Digit
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic;
ModIn : in std_logic;
ModOut : out std_logic;
Q : out std_logic_vector(3 downto 0)
);
end component;
signal ModVec : std_logic_vector(1 to N+1);
begin
-- The magic of generate!
g1 : for i in 1 to N generate
c1: Digit
port map
(Clock => Clock,
Reset => Reset,
Init => Init,
ModIn => ModVec(I+1),
ModOut => ModVec(I),
Q => Q(I*4-1 downto I*4-4));
end generate;
ModOut <= ModVec(1);
ModVec(N+1) <= ModIn;
end;
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity Digit is
port (Clock : in std_logic;
Reset : in std_logic; -- clear registers asynchronously
Init : in std_logic; -- initialise the BCD conversion
ModIn : in std_logic; -- modulus in from less significant digit
ModOut : out std_logic; -- modulus out to more significant digit
Q : out std_logic_vector(3 downto 0) -- BCD output
);
end;
architecture RTL of Digit is
signal Q_int : std_logic_vector(3 downto 0);
signal NextQ_int : std_logic_vector(2 downto 0);
signal NextModOut : std_logic;
begin
ShiftReg : process(Clock)
begin
if Rising_Edge(Clock) then
if reset = '1' then
Q_int <= (others => '0');
else
if Init = '1' then
Q_int <= (others => '0');
Q_int(0) <= ModIn; -- set LSB initialisation
else
Q_int <= NextQ_int & ModIn; -- shift left
end if;
end if;
end if;
end process;
-- Calculate the shift in the BCD register. Numbers between
-- 0 and 4 inclusive are doubled, by shifting by 1.
-- Numbers from 5 to 9 inclusive get mapped to 10, 12, 14,
-- 16, 18. This gives an modout of 1 (i.e. a carry to the
-- next digit), and the values 0, 2, 4, 6, 8.
BCDdoubler : process(Q_int)
begin
case Q_int is
when "0000" => -- Input 10s Units Result
NextQ_int <= "000"; -- 0 0 0 0
when "0001" =>
NextQ_int <= "001"; -- 1 0 2 2
when "0010" =>
NextQ_int <= "010"; -- 2 0 4 4
when "0011" =>
NextQ_int <= "011"; -- 3 0 6 6
when "0100" =>
NextQ_int <= "100"; -- 4 0 8 8
when "0101" =>
NextQ_int <= "000"; -- 5 1 0 10
when "0110" =>
NextQ_int <= "001"; -- 6 1 2 12
when "0111" =>
NextQ_int <= "010"; -- 7 1 4 14
when "1000" =>
NextQ_int <= "011"; -- 8 1 6 16
when "1001" =>
NextQ_int <= "100"; -- 9 1 8 18
when others =>
NextQ_int <= (others => '-');
end case;
end process;
-- if the numbers are greater than 5, we should generate a
-- carry out (modulus out) to the next digit.
ModOutGen : process(Q_int)
begin
case Q_int is
when "0101" | "0110" | "0111" | "1000" | "1001" =>
NextModOut <= '1';
when others =>
NextModOut <= '0';
end case;
end process;
-- When Init is high, we force ModOut to 0
ModOut <= NextModOut and (not Init);
Q <= Q_int;
end;
参考资料:http://www.doulos.com/knowhow/vhdl_designers_guide/models/binary_bcd/
BCD and Binary"
http://www.ingelec.uns.edu.ar/dclac2558/BCD2BIN.PDF
The basic idea is to shift data serially into a shift register. As each bit is shifted in, the accumulated sum is collected. Each shift effectively doubles the value of the binary number in the four bit shift register which is going to hold the converted BCD digit.
Each time a bit is shifted in, the value in the shift register is doubled. After four bits have been shifted in, if the original value is 0, 1, 2, 3, or 4, then the result is within the 0-9 range of a BCD digit and there is no action required.
If the value is 5, 6, 7, 8, or 9, then the doubled result is greater than 10, so a carry out (called ModOut in the code) is generated to represent the overflow into the tens column (i.e. into the next BCD digit). Here's a little table showing how to double each bit in BCD. All numbers shown are decimal.
input tens units result
0 0 0 0
1 0 2 2
2 0 4 4
3 0 6 6
4 0 8 8
5 1 0 10
6 1 2 12
7 1 4 14
8 1 6 16
9 1 8 18
The tens column thus represents an overflow into the next most significant BCD digit.
Does this all seems a bit baffling? There's a more thorough explanation in the application note referenced above.
The code is in three files:
digit.vhd
This contains a model for one four bit BCD digit, with carry in (ModIn) and carry out (ModOut). The digit has asynchronous reset, and an Init signal. The Init signal forces the carry out to zero at before a conversion starts.
bcdconv.vhd
This contains a generic N which allows you to specify the number of 4 bit BCD digits in the BCD converter. The generic is used to control a generate statement, which makes N instances of the Digit component described above.
bcdconvtb.vhd
This contains a testbench which applies a serial binary input representing a range of binary numbers, and then writes out the corresponding BCD equivalents
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use STD.textio.all;
entity BCDConvTB is
end;
architecture Bench of BCDConvTB is
component BCDConv
generic (N : positive);
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic;
ModIn : in std_logic;
ModOut : out std_logic;
Q : out std_logic_vector(N*4-1 downto 0)
);
end component;
-- hold an array of BCD digits
type BCDVectorT is array (natural range <>) of std_logic_vector(3 downto 0);
-- number of digits implemented in this test bench
constant N : positive := 5;
-- BCD array as a single std_logic_vector (packed in 4 bits at a
-- time)
subtype BcdT is std_logic_vector(N*4-1 downto 0);
signal Clock : std_logic;
signal Reset : std_logic;
signal Init : std_logic; -- Initialise BCD conversion
signal ModIn : std_logic; -- modulus in, if we wanted to
-- cascade lots of NDigits design entities
signal ModOut : std_logic; -- modulus out, same reason as ModIn
signal Q : BCDT; -- The outputs of the BCD conversion packed
-- into a std_logic_vector
-- Test bench control signal to ensure Clock stops when testing is over
signal StopClock : boolean;
-- Outputs of BCD conversion as an array of 4 bit digits.
signal BCDVec : BcdVectorT(1 to N);
-- Type to allow a table of test values
type TableT is array (natural range <>) of Integer;
-- some interesting values to test
constant Table : TableT := (17,18,19,20,21,22,23,30,40,50,
60,70,80,90,91,92,93,94,95,96,
97,98,99,100,101,302,
555,707,9999,10100, 99999);
signal TestInteger : Integer;
begin
UUT: BCDConv
generic map (N => N)
port map (
Clock => Clock,
Reset => Reset,
Init => Init,
ModIn => ModIn,
ModOut => ModOut,
Q => Q);
-- 100 ns clock. Clock loop stops automatically when the
-- stimulus process has finished, using the boolean signal StopClock
ClockGen: process
begin
while not StopClock loop
Clock <= '0';
wait for 50 ns;
Clock <= '1';
wait for 50 ns;
end loop;
wait;
end process;
--
-- Generate a set of values to test the Binary to BCD converter
--
StimGen: process
variable TestVal : BCDT;
variable L : LINE;
begin
Reset <= '0';
ModIn <= '0';
Init <= '0';
wait until falling_edge(Clock);
Reset <= '1';
wait until falling_edge(Clock);
Reset <= '0';
-- test all the values in the table
write(L, STRING'("Expected:"), LEFT, 10);
write(L, STRING'("Actual:"), LEFT, 10);
writeline(OUTPUT,L);
for I in Table'RANGE loop
-- convert integer value to std_logic_vector
TestVal := std_logic_vector(to_unsigned(Table(I), N*4));
-- assign the test value to an integer signal - easy to
-- disply in the simulator
TestInteger <= Table(I);
write(L, Table(I), LEFT, 10);
-- Loop round all the bits in the input vector
for J in BCDT'RANGE loop
-- initialise conversion if shifting in the first bit
if J = BCDT'LEFT then
Init<= '1';
else
Init <= '0';
end if;
ModIn <= TestVal(J);
wait until falling_edge(Clock);
end loop;
-- pack the result from the converter into a single std_logic_vector
-- (and write them as we go to check against the originals).
for J in 1 to N loop
BCDVec(J) <= Q(J*4-1 downto J*4-4);
write(L, to_integer(unsigned(Q(J*4-1 downto J*4-4))));
end loop;
writeline(OUTPUT,L);
end loop;
StopClock <= TRUE; -- tell the clock generator to stop
wait;
end process;
end;
-- must have a configuration for synopsys vhdl simulator
use work.all;
configuration cfg_BCDConvTB of BCDConvTB is
for Bench
end for;
end;
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity BCDConv is
generic (N : positive); -- number of digits
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic; -- initialise conversion
ModIn : in std_logic; -- carry in from outside
ModOut : out std_logic; -- carry out
Q : out std_logic_vector(4*N -1 downto 0) -- BCD result
);
end;
architecture RTL of BCDConv is
component Digit
port (Clock : in std_logic;
Reset : in std_logic;
Init : in std_logic;
ModIn : in std_logic;
ModOut : out std_logic;
Q : out std_logic_vector(3 downto 0)
);
end component;
signal ModVec : std_logic_vector(1 to N+1);
begin
-- The magic of generate!
g1 : for i in 1 to N generate
c1: Digit
port map
(Clock => Clock,
Reset => Reset,
Init => Init,
ModIn => ModVec(I+1),
ModOut => ModVec(I),
Q => Q(I*4-1 downto I*4-4));
end generate;
ModOut <= ModVec(1);
ModVec(N+1) <= ModIn;
end;
-----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity Digit is
port (Clock : in std_logic;
Reset : in std_logic; -- clear registers asynchronously
Init : in std_logic; -- initialise the BCD conversion
ModIn : in std_logic; -- modulus in from less significant digit
ModOut : out std_logic; -- modulus out to more significant digit
Q : out std_logic_vector(3 downto 0) -- BCD output
);
end;
architecture RTL of Digit is
signal Q_int : std_logic_vector(3 downto 0);
signal NextQ_int : std_logic_vector(2 downto 0);
signal NextModOut : std_logic;
begin
ShiftReg : process(Clock)
begin
if Rising_Edge(Clock) then
if reset = '1' then
Q_int <= (others => '0');
else
if Init = '1' then
Q_int <= (others => '0');
Q_int(0) <= ModIn; -- set LSB initialisation
else
Q_int <= NextQ_int & ModIn; -- shift left
end if;
end if;
end if;
end process;
-- Calculate the shift in the BCD register. Numbers between
-- 0 and 4 inclusive are doubled, by shifting by 1.
-- Numbers from 5 to 9 inclusive get mapped to 10, 12, 14,
-- 16, 18. This gives an modout of 1 (i.e. a carry to the
-- next digit), and the values 0, 2, 4, 6, 8.
BCDdoubler : process(Q_int)
begin
case Q_int is
when "0000" => -- Input 10s Units Result
NextQ_int <= "000"; -- 0 0 0 0
when "0001" =>
NextQ_int <= "001"; -- 1 0 2 2
when "0010" =>
NextQ_int <= "010"; -- 2 0 4 4
when "0011" =>
NextQ_int <= "011"; -- 3 0 6 6
when "0100" =>
NextQ_int <= "100"; -- 4 0 8 8
when "0101" =>
NextQ_int <= "000"; -- 5 1 0 10
when "0110" =>
NextQ_int <= "001"; -- 6 1 2 12
when "0111" =>
NextQ_int <= "010"; -- 7 1 4 14
when "1000" =>
NextQ_int <= "011"; -- 8 1 6 16
when "1001" =>
NextQ_int <= "100"; -- 9 1 8 18
when others =>
NextQ_int <= (others => '-');
end case;
end process;
-- if the numbers are greater than 5, we should generate a
-- carry out (modulus out) to the next digit.
ModOutGen : process(Q_int)
begin
case Q_int is
when "0101" | "0110" | "0111" | "1000" | "1001" =>
NextModOut <= '1';
when others =>
NextModOut <= '0';
end case;
end process;
-- When Init is high, we force ModOut to 0
ModOut <= NextModOut and (not Init);
Q <= Q_int;
end;
参考资料:http://www.doulos.com/knowhow/vhdl_designers_guide/models/binary_bcd/
展开全部
最最简单的方法是调用 IEEE.STD_LOGIC_ARITH 库,里面有 十进制数=conv_integer(写二进制数) 的函数,还有conv_std_logic_vector(十进制数,二进制数的位数) 用这两个函数稍微用一下心就可以了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这个程序是我在你的一个提问中回答的,,这就是一个2输入与非门的VHDL程序啊,如果不是你要求的,你把SN7401 四2输入端与非门(OC)要实现的功能发上来
追问
什么意思?什么与非门....
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询