Communication PC-DE0 Nano using UART - vhdl

I'm trying to connect my FPGA with my laptop using the serial protocol. For that purpose, I implemented the UART protocol on the FPGA side.
The connection between the FPGA and the Laptop is done with the UART-TTL to USB converter. I Get the wrong frame on the Laptop side.
Thus, I analyse my frame continuously using a logic analyzer, I observed that the frame sent wasn't stable, i.e sometimes a wrong frame is received instead of the one sent.
Below is the code for the serial core :
library ieee ;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity TX is
port(
CLK: in std_logic;
START: in std_logic;
BUSY : out std_logic;
DATA: in std_logic_vector(7 downto 0);
TX_LINE: out std_logic
);
end TX;
architecture MAIN of TX is
signal PRSCL : integer range 0 to 5208:=0;
signal index : integer range 0 to 9:=0;
signal DATAFLL : std_logic_vector (9 downto 0);
signal TX_FLAG: STD_LOGIC:='0';
begin
process(CLK)
begin
if(CLK'EVENT and CLK='1') then
if(TX_FLAG='0' and START='1') then
TX_FLAG<='1';
BUSY<='1';
DATAFLL(0)<='0';
DATAFLL(9)<='1';
DATAFLL(8 downto 1)<=DATA;
TX_LINE<='1';
end if;
-- send data , 50MHz /9600=5208 (9600: the baudrate)
IF(TX_FLAG='1') then
IF (PRSCL <5207) then
PRSCL<=PRSCL+1;
else
PRSCL<=0;
end if;
IF(PRSCL=2600)THEN
TX_LINE<=DATAFLL(INDEX);
IF(INDEX<9)THEN
INDEX<=INDEX+1;
ELSE
TX_FLAG<='0';
BUSY<='0';
INDEX<=0;
END IF;
END IF;
END IF;
END IF;
end process ;
end MAIN;
The control unit to instantiate the serial core is below :
library ieee ;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity UART is
port (
CLOCK_50: in std_logic;
SW: in std_logic_vector(3 downto 0);
KEY: in std_logic_vector(1 downto 0);
LEDG : out std_logic_vector (7 downto 0);
UART_TXD : out std_logic;
UART_RXD: in std_logic
);
end UART ;
ARCHITECTURE MAIN OF UART IS
SIGNAL TX_DATA: STD_LOGIC_VECTOR(7 downto 0);
SIGNAL TX_START: STD_LOGIC:='0';
SIGNAL TX_BUSY: STD_LOGIC:='0';
SIGNAL RX_DATA: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RX_BUSY: STD_LOGIC:='0';
COMPONENT TX
PORT(
CLK:IN STD_LOGIC;
START:IN STD_LOGIC;
BUSY:OUT STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(7 downto 0);
TX_LINE:OUT STD_LOGIC
);
END COMPONENT TX;
BEGIN
C1: TX PORT MAP (CLOCK_50,TX_START,TX_BUSY,TX_DATA,UART_TXD);
--C2: RX PORT MAP (CLOCK_50,UART_RXD,RX_DATA,RX_BUSY);
PROCESS(CLOCK_50)
BEGIN
IF(CLOCK_50'EVENT AND CLOCK_50='1')THEN
IF(KEY(0)='1' AND TX_BUSY='0')THEN -- Key(0)='0' MEAN that the key is pressed
TX_DATA<="0000" & SW(3 DOWNTO 0);
TX_START<='1';
LEDG<=TX_DATA;
ELSE
TX_START<='0';
TX_DATA<=(others=>'0') ;
END IF;
END IF;
END PROCESS;
END MAIN;
Thanks for you help.
Best regards,

Any asynchronous input have to be resynchronized before use, otherwise your circuit will become metastable and erratic behaviour will follow. On your top level, sw and key are asynchronous.
A synchronization circuit is typically 2 cascaded flip-flops, only the output of the second flip-flop should be used in your code:
...
signal sw_resync1 : std_logic_vector(3 downto 0);
signal sw_resync2 : std_logic_vector(3 downto 0);
signal key_resync1 : std_logic_vector(3 downto 0);
signal key_resync2 : std_logic_vector(3 downto 0);
begin
RESYNC: process(CLOCK_50)
begin
if (CLOCK_50'event and CLOCK_50 = '1') then
SW_resync1 <= SW;
SW_resync2 <= SW_resync1;
KEY_resync1 <= KEY;
KEY_resync2 <= KEY_resync1;
end if;
end process RESYNC;
...
IF(KEY_resync2(0)='1' AND TX_BUSY='0')THEN -- Key(0)='0' MEAN that the key is pressed
TX_DATA<="0000" & SW_resync2(3 DOWNTO 0);
...
You should also be aware that mechanical inputs (suck as sw and key) should be debounced or you will read several transitions for the same key stroke.

Related

How to eliminate the logic gate and the adder

The logic gate in the RTL view was a latch previously. As an answer suggests, I assign each input with outputs. And the latch turns into a logic gate. I don't know whether it is a correct way to solve the problem. There is also an adder connected to the counter.
I want to eliminate the adder and the logic gate. (??? T^T).
What should I modify?
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use IEEE.std_logic_unsigned.all;
entity mux8x1 is port( input: in std_logic_vector( 7 downto 0); clk: in std_logic; --s: buffer std_logic; --rst : in std_logic; --d: buffer std_logic; q: out std_logic_vector (7 downto 0) --o: buffer std_logic_vector (3 downto 0) ); end mux8x1;
architecture mux of mux8x1 is signal count : std_logic_vector(3 downto 0);
--signal count_state: std_logic_vector (3 downto 0); signal serial: std_logic;
--shiftregister
signal internal: std_logic_vector (7 downto 0); signal d: std_logic;
begin --【The counter】 process(clk) --variable internal: std_logic_vector (7 downto 0); --variable d: std_logic; --variable initial: std_logic_vector (7 downto 0) :="01010101";
begin
if (clk'event and clk = '1') then
count <= count + 1;
end if;
end process;
--count_state <= count; --To divide the counter
--section1 for the counter --8x1 multiplxer combined with counter
process(count,input,clk) --variable serialin: std_logic; begin --serialin:='0'; if (count(3) <='0') then case count(2 downto 0) is --8 possible states for PToS
when "000"=> serial <=input(0);
when "001"=> serial <=input(1);
when "010"=> serial <=input(2);
when "011"=> serial <=input(3);
when "100"=> serial <=input(4);
when "101"=> serial <=input(5);
when "110"=> serial <=input(6);
when "111"=> serial <=input(7);
when others => serial <= '0'; end case; else serial <='0';
end if; --serial<=serialin; end process;
-- end if; end mux;
The following is the RTL viewer.
enter image description here
The reason that you get a latch, is because you do not apply a signal value to "serial" in any case when the process is started: Then "serial" keeps its old value which leads to a latch at synthesis, where this kept value is taken from.
So it is a good idea to assign a default value to any signal you assign values to in a process.
When you want to get a register (triggered by a clock edge) you must use a process which is only sensitive to a clock signal (and a reset signal) and uses as a condition "rising_edge(clk)". Of course you do not need a default assignment here.

vhdl and gate returning unknown value

I was implementing a multiplexer, but and gate returning "x" for no reason, pls help.
As you can see in screenshot, result just became "x" from "1".
i did a testbench for and gate, it works fine on its own.
It should have been a 3 bit 4:1 multiplexer.
this is the problem
This is source, i am using ghdl.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY mux41 IS
PORT (
i1 : IN std_logic_vector(2 DOWNTO 0);
i2 : IN std_logic_vector(2 DOWNTO 0);
i3 : IN std_logic_vector(2 DOWNTO 0);
i4 : IN std_logic_vector(2 DOWNTO 0);
sel : IN std_logic_vector(1 DOWNTO 0);
y : OUT std_logic_vector(2 DOWNTO 0)
);
END mux41;
ARCHITECTURE rtl OF mux41 IS
COMPONENT andgate
PORT (
input1 : IN std_logic;
input2 : IN std_logic;
input3 : IN std_logic;
and_output : OUT std_logic
);
END COMPONENT;
COMPONENT orgate
PORT (
input1 : IN std_logic;
input2 : IN std_logic;
input3 : IN std_logic;
input4 : IN std_logic;
or_output : OUT std_logic
);
END COMPONENT;
signal not_sel : std_logic_vector(1 DOWNTO 0);
signal and_result : std_logic_vector(3 DOWNTO 0);
signal or_result : std_logic_vector(2 DOWNTO 0);
BEGIN
not_sel <= not sel;
and_gate_assignment : for i in 0 to 2 generate
and_output1: andgate port map(input1=>i1(i), input2=>not_sel(1), input3=>not_sel(0), and_output=>and_result(0));
and_output2: andgate port map(input1=>i2(i), input2=>not_sel(1), input3=>sel(0), and_output=>and_result(1));
and_output3: andgate port map(input1=>i3(i), input2=>sel(1), input3=>not_sel(0), and_output=>and_result(2));
and_output4: andgate port map(input1=>i4(i), input2=>sel(1), input3=>sel(0), and_output=>and_result(3));
or_output: orgate port map(input1=>and_result(0), input2=>and_result(1), input3=>and_result(2), input4=>and_result(3), or_output=>or_result(i));
end generate and_gate_assignment;
y <= or_result;
END rtl;
Here is the and gate;
library ieee;
use ieee.std_logic_1164.all;
entity andgate is
port (
input1 : in std_logic;
input2 : in std_logic;
input3 : in std_logic;
and_output : out std_logic
);
end andgate;
architecture rtl of andgate is
signal and1 : std_logic;
signal and2 : std_logic;
begin
and1 <= input1 and input2;
and2 <= and1 and input3;
and_output <= and2;
end rtl;
there is not much to this really, could this be a timing issue?
Adding orgate's entity and architecture
use ieee.std_logic_1164.all;
entity orgate is
port (
input1: in std_logic;
input2: in std_logic;
input3: in std_logic;
input4: in std_logic;
or_output: out std_logic
);
end entity;
architecture foo of orgate is
begin
or_output <= input1 or input2 or input3 or input4;
end architecture;
and a testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mux41_tb is
end entity;
architecture foo of mux41_tb is
signal i1: std_logic_vector(2 downto 0);
signal i2: std_logic_vector(2 downto 0);
signal i3: std_logic_vector(2 downto 0);
signal i4: std_logic_vector(2 downto 0);
signal sel: std_logic_vector(1 downto 0);
signal y: std_logic_vector(2 downto 0);
begin
DUT:
entity work.mux41
port map (
i1 => i1,
i2 => i2,
i3 => i3,
i4 => i4,
sel => sel,
y => y
);
STIMULI:
process
begin
for i in 0 to 7 loop
i1 <= std_logic_vector(to_unsigned(i, 3));
for j in 0 to 7 loop
i2 <= std_logic_vector(to_unsigned(j, 3));
for k in 0 to 7 loop
i3 <= std_logic_vector(to_unsigned(k, 3));
for m in 0 to 7 loop
i4 <= std_logic_vector(to_unsigned(m, 3));
for n in 0 to 3 loop
sel <= std_logic_vector(to_unsigned(n,2));
wait for 10 ns;
end loop;
end loop;
end loop;
end loop;
end loop;
wait;
end process;
end architecture;
allows you readers to replicate your problem.
Adding more signals may help to understand the problem:
'X's come from driver conflict. Here there are multiple drivers connected to and_result(3 downto 0) across the generated blocks. When all the drivers are '0' the signal is resolved to '0'. When there is a conflict there's an 'X'.
The solution is to move the and_result declaration to the generate statement block declarative region (with a following begin separating declarations from statements):
signal not_sel : std_logic_vector(1 DOWNTO 0);
-- signal and_result : std_logic_vector(3 DOWNTO 0); -- MOVE FROM HERE
signal or_result : std_logic_vector(2 DOWNTO 0);
BEGIN
not_sel <= not sel;
and_gate_assignment : for i in 0 to 2 generate
signal and_result : std_logic_vector(3 DOWNTO 0); -- TO HERE
BEGIN -- AND ADD A FOLLOWING BEGIN
and_output1: andgate port map(input1=>i1(i), input2=>not_sel(1), input3=>not_sel(0), and_output=>and_result(0));
And that gives you
the intended result.
The generate statement represents zero or more block statements in elaboration. Here each of the three block statement contains a 4 to 1 multiplexer for a std_logic element of a slice.
An individual multiplexer has signal nets connecting the output of each of four andgate instantiations to an orgate instantiation. By relying on a common declaration for and_result you've shorted the andgate outputs together across all three blocks.
Moving the and_result declaration into the generate statement block declarative region results in it being replicated for each generated block statement. Because a block statement is a declarative region those three declarations of and_result aren't visible outside each generated block due to scope and visibility rules which match them being local to each block in a hierarchical block diagram - the three and_result elements are no longer connected to all three blocks. This eliminates multiple drivers.

How to transfer data from one process to another?

As an example, in the first process I have a binary number that I want to transfer to a second process. How to I do this?
Do i need to use something called a FIFO?
If I need to use a FIFO must I use it? Are there any alternatives?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity pwm_control_1 is
port (
--inputs and outputs for clock divider-------------------------------------------------------
clk_in : in std_logic ;
clr : in std_logic;
pwm_testing: out bit;
pwm_out: out bit;
key_0:in bit;
green_led:out bit
);
end pwm_control_1;
architecture Behavioral of pwm_control_1 is
signal compare:std_logic_vector( 8 downto 0);
signal q:std_logic_vector (8 downto 0);-- q is for the clock divider ,q can get till 23
signal q_1:std_logic_vector (23 downto 0);
signal pwm_testing_signal : bit;
signal test : std_logic_vector(8 downto 0);
signal step_10_dc : std_logic_vector(8 downto 0);
signal step_5_dc : std_logic_vector(8 downto 0);
signal duty_cycle_0 : std_logic_vector(8 downto 0);
signal duty_cycle_counter : std_logic_vector(8 downto 0);
signal duty_cycle_counter_refresh : std_logic_vector(8 downto 0);
begin
test <= "000000000";
step_10_dc <= "000110011";
step_5_dc <= "000011010";
duty_cycle_counter <= "000000000";
duty_cycle_counter_refresh <= "000000000";
--
key_testing :process (key_0)
begin
if (key_0='0') then
green_led <='1';
duty_cycle_counter <= (duty_cycle_counter+step_5_dc);-- counter for adding the limit of the PWM
else
green_led <='0';
end if;
end process key_testing;
` duty_cycle_counter_refresh <=duty_cycle_counter;
add_5_or_10_duty_cycle :process(clk_in,clr,q ,key_0)
begin
if (clk_in'event and clk_in='1') then -- starting the q counter
q<= q+1; --first I torn on the counter q that is used for clock driver then
if (q<=(duty_cycle_counter_refresh )) then pwm_testing_signal <='1';
else
pwm_testing_signal <='0';
end if ;
end if;
end process add_5_or_10_duty_cycle;
pwm_testing <=pwm_testing_signal;
end Behavioral;

Pseudo Random Number Generator using LFSR in VHDL

I'm having a bit of trouble creating a prng using the lfsr method. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0);
begin
PROCESS(clock)
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN Qt <= "00000000";
ELSE Qt <= seed;
END IF;
temp <= Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
--Qt <= temp & Qt(7 downto 1);
END IF;
END PROCESS;
check <= temp;
Q <= Qt;
end Behavioral;
Here is the simulation I have ran:
prng sim
Firstly, the check output is just there so I can monitor the output of the temp signal. Secondly, the line that is commented out is what is causing the problem.
As can be seen from the simulation, on the first rising edge of the clock, the Qt signal reads the seed. However, and this is my question, for some reason the temp signal only XORs the bits of the Qt signal on the second rising edge of the clock. It remains undefined on the first clock pulse. Why is that? If it operated on the first rising edge right after the Qt signal reads the seed, then I could uncomment the line that shifts the bits and it would solve my problem. Any help would be much appreciated!
Here is the test bench if anyone cares:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1<='0'; wait for 50ns;
clock1<='1'; wait for 50ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1<='0'; wait for 900ns;
END PROCESS;
end bench;
I made some slight modifications to what you had (you are pretty much there though); I don't think the LFSR would step properly otherwise. I added an enable signal to the LFSR so you can effectively control when you want it to step. Resulting sim is here.
Just as a sidenote, you could also include a load and seed inputs if you wanted to seed the LFSR with a different value (instead of making it const).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
-- constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
--signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0) := x"01";
begin
PROCESS(clock)
variable tmp : STD_LOGIC := '0';
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN
-- credit to QuantumRipple for pointing out that this should not
-- be reset to all 0's, as you will enter an invalid state
Qt <= x"01";
--ELSE Qt <= seed;
ELSIF en = '1' THEN
tmp := Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
Qt <= tmp & Qt(7 downto 1);
END IF;
END IF;
END PROCESS;
-- check <= temp;
check <= Qt(7);
Q <= Qt;
end Behavioral;
And tb:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
signal en : STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
en => en,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1 <= '0'; wait for 50 ns;
clock1 <= '1'; wait for 50 ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1 <= '0';
en <= '1';
wait for 900 ns;
END PROCESS;
end bench;

VHDL component output returns zeros

I'm writing something in VHDL about an essay and I'm facing a strange situation. I've written some components, simulated and tested them, and everything seems to works fine. However, when simulating the top entity, I'm getting zeros as a result! Please take a look at the following listings:
Top Entity:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity foobar is
port ( data_i : in std_logic_vector(39 downto 0);
sum_12bit_o : out std_logic_vector(11 downto 0)
);
end foobar;
architecture Behavioral of foobar is
--Declare components
component four_10bit_word_adder is
port( --Input signals
a_byte_in: in std_logic_vector(9 downto 0);
b_byte_in: in std_logic_vector(9 downto 0);
c_byte_in: in std_logic_vector(9 downto 0);
d_byte_in: in std_logic_vector(9 downto 0);
cin: in std_logic;
--Output signals
val12bit_out: out std_logic_vector(11 downto 0)
);
end component;
-- Signal declaration
signal int: std_logic_vector(11 downto 0);
signal intdata: std_logic_vector(39 downto 0);
begin
intdata <= data_i; --DEBUG
U1: four_10bit_word_adder port map (intdata(39 downto 30), intdata(29 downto 20),
intdata(19 downto 10), intdata(9 downto 0),
'0', int);
end Behavioral;
four_10bit_word_adder:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity four_10bit_word_adder is
generic (
bits: integer := 10
);
port( --Input signals
a_byte_in: in std_logic_vector(bits-1 downto 0);
b_byte_in: in std_logic_vector(bits-1 downto 0);
c_byte_in: in std_logic_vector(bits-1 downto 0);
d_byte_in: in std_logic_vector(bits-1 downto 0);
cin: in std_logic;
--Output signals
val12bit_out: out std_logic_vector(bits+1 downto 0)
);
end four_10bit_word_adder;
architecture Behavioral of four_10bit_word_adder is
-- Component Declaration
component compressor_4_2 is
port(a,b,c,d,cin : in std_logic;
cout, sum, carry : out std_logic
);
end component;
--------------------------------------------------------+
component generic_11bit_adder
port (
A: in std_logic_vector(10 downto 0); --Input A
B: in std_logic_vector(10 downto 0); --Input B
CI: in std_logic; --Carry in
O: out std_logic_vector(10 downto 0); --Sum
CO: out std_logic --Carry Out
);
end component;
--------------------------------------------------------+
-- Declare internal signals
signal int: std_logic_vector(bits-1 downto 0); -- int(8) is the final Cout signal
signal byte_out: std_logic_vector(bits-1 downto 0);
signal carry: std_logic_vector(bits-1 downto 0);
signal int11bit: std_logic_vector(bits downto 0);
-- The following signals are necessary to produce concatenated inputs for the 10-bit adder.
-- See the paper for more info.
signal Concat_A: std_logic_vector(bits downto 0);
signal Concat_B: std_logic_vector(bits downto 0);
signal co : std_logic;
begin
A0: compressor_4_2 port map (a_byte_in(0), b_byte_in(0),
c_byte_in(0), d_byte_in(0),
'0', int(0), byte_out(0), carry(0));
instances: for i in 1 to bits-1 generate
A: compressor_4_2 port map (a_byte_in(i), b_byte_in(i),
c_byte_in(i), d_byte_in(i), int(i-1),
int(i), byte_out(i), carry(i));
end generate;
R9: generic_11bit_adder port map (Concat_A, Concat_B, '0', int11bit, co);
Concat_A <= int(8) & byte_out;
Concat_B <= carry & '0';
process (co)
begin
if (co = '1') then
val12bit_out <= '1' & int11bit;
else
val12bit_out <= '0' & int11bit;
end if;
end process;
end Behavioral;
4:2 Compressor
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity compressor_4_2 is
port(a,b,c,d,cin : in std_logic;
cout, sum, carry : out std_logic
);
end compressor_4_2;
architecture Behavioral of compressor_4_2 is
-- Internal Signal Definitions
signal stage_1: std_logic;
begin
stage_1 <= d XOR (b XOR c);
cout <= NOT((b NAND c) AND (b NAND d) AND (c NAND d));
sum <= (a XOR cin) XOR stage_1;
carry <= NOT((a NAND cin) AND (stage_1 NAND cin) AND (a NAND stage_1));
end Behavioral;
Generic 11-bit Adder:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity generic_11bit_adder is
generic (
bits: integer := 11
);
port (
A: in std_logic_vector(bits-1 downto 0);
B: in std_logic_vector(bits-1 downto 0);
CI: in std_logic;
O: out std_logic_vector(bits-1 downto 0);
CO: out std_logic
);
end entity generic_11bit_adder;
architecture Behavioral of generic_11bit_adder is
begin
process(A,B,CI)
variable sum: integer;
-- Note: we have one bit more to store carry out value.
variable sum_vector: std_logic_vector(bits downto 0);
begin
-- Compute our integral sum, by converting all operands into integers.
sum := conv_integer(A) + conv_integer(B) + conv_integer(CI);
-- Now, convert back the integral sum into a std_logic_vector, of size bits+1
sum_vector := conv_std_logic_vector(sum, bits+1);
-- Assign outputs
O <= sum_vector(bits-1 downto 0);
CO <= sum_vector(bits); -- Carry is the most significant bit
end process;
end Behavioral;
I've tried a ton of things, but without any success. Do you have any idea what am I doing wrong? Sorry for the long question and thank you for your time.
Take a look at your process to generate val12bit_out in your four_10bit_word_adder entity. It's missing an input.
Also, there are several other issues. Fixing this one issue will not fix everything. But once you fix it, I think things will be a lot more clear.

Resources