问题描述
你好,我试图从几个1位ALU中创建一个16位ALU
我创建了一个名为basic_alu1的程序包,其中包含1位ALU的一个组件,其代码为:
Hello I am trying to create a 16-bit ALU from several 1-bit ALUs I created a package named basic_alu1 which contains a component of the 1-bit ALU.The code for this is:
library ieee;
use ieee.std_logic_1164.all;
package basic_alu1 is
component alu1
port (a, b: std_logic_vector(1 downto 0);
m: in std_logic_vector(1 downto 0);
result: out std_logic_vector(1 downto 0));
end component;
end package basic_alu1;
library ieee;
use ieee.std_logic_1164.all;
entity alu1 is
port (a, b: std_logic_vector(1 downto 0);
m: in std_logic_vector(1 downto 0);
result: out std_logic_vector(1 downto 0));
end alu1;
architecture arch1 of alu1 is
begin
process(a, b, m)
begin
case m is
when "00" =>
result <= a + b;
when "01" =>
result <= a + (not b) + 1;
when "10" =>
result <= a and b;
when "11" =>
result <= a or b;
end case
end process
end arch1
因此,在为了创建16位ALU,我正在使用for生成循环并实例化alu1的多个副本。我的问题是如何将计数器带入和带出计数器以及如何进行溢出检查。我的主要代码是:
So, in order to create the 16 bit ALU I am using a for generate loop and instantiate multiple copies of alu1. My question is how can I take the counter in and counter out and how can I have an overflow check. My main code is :
library ieee;
use ieee.std_logic_1164.all;
use work.basic_alu1.all;
entity alu16 is
port (input_a : in std_logic_vector(15 downto 0);
input_b : in std_logic_vector(15 downto 0);
mode : in std_logic_vector(1 downto 0)
result_x4 : out std_logic);
end alu16;
architecture structural of alu16 is
begin
G1 : for i in 0 to 15 generate
begin
alu_16 : entity work.basic_alu1
port map (
a => input_a(i),
b => input_b(i),
m => mode,
result => result_x4(i));
end generate;
推荐答案
下面是如何创建N的示例位加法器组件。首先,您需要创建一个完整的加法器,该加法器还要考虑进位。
Here is an example of how you can create a N-bit adder component. First of all you need to create a full adder which is a adder that also takes a carry in bit into account.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY fullAdder IS
PORT (a : IN STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
y : OUT STD_LOGIC;
cout : OUT STD_LOGIC);
END fullAdder;
ARCHITECTURE arch_fullAdder OF fullAdder IS
BEGIN
y <= a XOR b XOR cin;
cout <= (a AND b) OR
(b AND cin) OR
(a AND cin);
END arch_fullAdder;
使用此1位加法器时,可以通过生成多个来轻松生成N位波纹进位
When you have this 1-bit adder you can easily generate a N-bit ripple carry by generating multiple cells of the full adder we have above.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ripple_adder IS
GENERIC (WIDTH : NATURAL := 32);
PORT(a : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
cin : IN STD_LOGIC := '0';
y : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
cout : OUT STD_LOGIC);
END ripple_adder;
ARCHITECTURE arch_ripple_adder OF ripple_adder IS
SIGNAL carry : STD_LOGIC_VECTOR(WIDTH DOWNTO 0);
SIGNAL y_temp : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
COMPONENT fullAdder IS
PORT(a : IN STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
y : OUT STD_LOGIC;
cout : OUT STD_LOGIC);
END COMPONENT;
BEGIN
N_bit_adder_generate : FOR N IN 0 TO WIDTH-1 GENERATE
N_bit_adder : fullAdder
PORT MAP(a => a(N),
b => b (N),
cin => carry(N),
y => y_temp(N),
cout => carry(N + 1));
END GENERATE;
carry(0) <= cin;
cout <= carry(WIDTH);
y <= y_temp;
END arch_ripple_adder;
拥有加法器后,您可以轻松地将加法器组件放入ALU中并指定不同的操作
When you have the adder you can easily put the adder component into an ALU and specify the different operations that the ALU should be able to perform.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ALU IS
GENERIC(WIDTH : NATURAL := 32);
PORT(Clk : IN STD_LOGIC := '0';
Reset : IN STD_LOGIC := '0';
A : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
B : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
Op : IN STD_LOGIC_VECTOR(3 DOWNTO 0) := (OTHERS => '0');
Outs : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0));
END ALU;
ARCHITECTURE arch_ALU OF ALU IS
COMPONENT ripple_adder
PORT(a : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
cin : IN STD_LOGIC := '0';
y : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
cout : OUT STD_LOGIC);
END COMPONENT;
SIGNAL RCA_output : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL B_neg : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL c_flag : STD_LOGIC := '0';
SIGNAL c_reg : STD_LOGIC := '0';
SIGNAL cin : STD_LOGIC := '0';
BEGIN
RCA_comp : ripple_adder
PORT MAP(a => A,
b => B_neg,
Cin => cin,
y => RCA_output,
Cout => c_flag);
WITH Op SELECT
B_neg <= NOT(B) WHEN "1000",
B WHEN OTHERS;
WITH Op SELECT
cin <= '1' WHEN "1000", -- SUB
c_reg WHEN "0111", -- ADDC
'0' WHEN OTHERS; -- ADD/ADDS
ALU_Process:
PROCESS(Clk, Reset)
BEGIN
IF Reset = '0' THEN
Outs <= (OTHERS => '0');
c_reg <= '0';
ELSIF rising_edge(Clk) THEN
CASE Op IS
WHEN "0001" => Outs <= A AND B;
WHEN "0010" => Outs <= A OR B;
WHEN "0011" => Outs <= A NOR B;
WHEN "0100" => Outs <= A XOR B;
WHEN "0101" => Outs <= RCA_output; -- ADD
WHEN "0110" => Outs <= RCA_output; -- ADDS
c_reg <= c_flag;
WHEN "0111" => Outs <= RCA_output; -- ADDC
WHEN "1000" => Outs <= RCA_output; -- SUB
WHEN "1001" => Outs <= STD_LOGIC_VECTOR(UNSIGNED(A) SLL to_integer(UNSIGNED(B(4 DOWNTO 0))));
WHEN "1010" => Outs <= STD_LOGIC_VECTOR(unsigned(A) SRL to_integer(UNSIGNED(B(4 DOWNTO 0))));
WHEN "1011" => Outs <= STD_LOGIC_VECTOR(shift_right(SIGNED(A),to_integer(UNSIGNED(B(4 DOWNTO 0)))));
WHEN OTHERS => Outs <= (OTHERS => '0');
END CASE;
END IF;
END PROCESS;
END arch_ALU;
但是该ALU并不那么复杂,没有那么多操作,但是可以轻松实现该功能添加。希望我给您的示例代码能对您有所帮助。
This ALU however is not that complex and don´t have that many operations but that functionality can easily be added. I hope the example code I have given you will help you.
这篇关于使用1位ALU制作16位ALU的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!