Привет, я пытаюсь создать 32-разрядный сумматор с несколькими кодами операций, и у меня это работает достаточно хорошо, за исключением двух случаев, и я не могу найти, что их вызывает. Возможно ты можешь помочь мне?Реализация ALU с ADDER
Сбой при вычитании по какой-либо причине по ошибке и по ошибке ADDC не может вычислить правильный вывод, когда он должен использовать бит переноса в c_reg, который был создан операцией ADDS.
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 adder
PORT(OpA : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
OpB : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
Cin : IN STD_LOGIC;
Cout : OUT STD_LOGIC;
Result : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0));
END COMPONENT;
SIGNAL adder_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
adder_comp : adder
PORT MAP(OpA => A,
OpB => B_neg,
Cin => cin,
Result => adder_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)
BEGIN
IF Reset = '0' THEN
Outs <= (OTHERS => '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 <= adder_output; -- ADD
WHEN "0110" => Outs <= adder_output; -- ADDS
c_reg <= c_flag;
WHEN "0111" => Outs <= adder_output; -- ADDC
WHEN "1000" => Outs <= adder_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;
Только операция добавляет должна написать это вынос в c_reg и эксплуатацию ADDC следует принимать c_reg во внимание при расчете на его выход Сумматор протестирован и работают правильно, так что проблема не в конструкции сумматора ,
Прежде всего, я хотел бы узнать проблему вычитания, потому что это делает вычитание, но результат немного откусил .. Например:
A: h'E6A4960F B: h'7B494E34 Op: d'1000 Ушли: h'6B5B47DA в то время как он должен быть h'6B5B47DB
A: h'EFDE31A3 B: h'0BCAB8FA Op: d'1000 Out: h'E41378BB в то время как должен быть h'E41378A9
Можете ли вы рассказать о своей ошибке? Потому что я, конечно, не могу ..
Да, спасибо за отличный ответ, мне дали сумматор, и это сказал, что он проверен и проверен. Я просто испытал один и тот же дизайн с моим дизайном переноса пульсаций, и он работал безупречно. Думаю, мне придется отлаживать сумку тогда :) – Pethead