I am have an assignment to make an 8 Input NANDGate using a for loop.
This is what I have so far:
entity NANDGATE is
port (
A: in std_logic_vector (7 downto 0);
X: out std_logic
);
end entity;
architecture behavioral of NANDGATE is
begin
process (A)
begin
op <= ’0′;
for i in 7 downto 0 loop
if inp(i) = ’0′ then
op <=’1′;
end if;
end loop;
end process;
end architecture behavioral;
I just starting learning about VHDL I am not that good at it, I hope someone can help me so I can understand.
If you're using VHDL 2008, simply write:
op <= nand A;
No for loop needed.
Related
I am struggling with type conversion in vhdl. I am pretty new to vhdl and apologize, if this is a really stupid question.
But what i want to do is, i want to go through the input vector and add all bits together to form an integer.
For example "11001010" shall result in 4 (or "100"). And "11101010" would result for example in 6 (or "110"). How can i achieve that?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity xyz is
port(
input: in std_logic_vector(7 downto 0);
output: out std_logic_vector(7 downto 0)
);
end entity;
architecture behaviour of xyz is
signal temp : integer := 0;
begin
evaluate_input :process is
begin
for i in input'left downto input'right loop
temp <= temp + to_integer(unsigned(input(i)));
end loop;
wait;
end process;
stop_simulation :process is
begin
wait for 100 ns; --run the simulation for this duration
assert false
report "simulation ended"
severity failure;
end process;
end xyz;
Don't think to complicated. You want to calculate the hamming weight.
for i in input'range loop
temp <= temp + (1 when (input(i) = '1') else 0);
end loop;
Or with your proposed way:
for i in input'range loop
temp <= temp + to_integer(unsigned(input(i downto i)));
end loop;
unsigned(...) needs an array of std_logic_vector. By using just i, you get a single std_logic. Whereas, i downto i creates another std_logic_vector of length 1, which can be used in unsigned.
I am writing a VHDL code to impelemt 8 bit serial adder with accumulator.
When i do simulation, the output is always zeros! And some times it gives me the same number but with a shift !
I dont know what is the problem, i tried to put A,B as inout but didnt work as well. Can anybody help please.
This is the code:
entity SA is
Port ( st : in std_logic;
A,B: inout std_logic_vector ( 7 downto 0);
clk : in std_logic;
acc : out bit_vector(7 downto 0)); end SA;
architecture Behavioral of SA is
signal ps,ns: integer range 0 to 7;
signal C,D: bit_vector (7 downto 0);
signal ci,ciplus,si,sh:bit;
begin
si<=A(0) xor B(0) xor ci ;
ciplus <=(A(0) and B(0)) or (A(0) and ci ) or ( B(0) and ci );
process(ps,st)
begin
case ps is
when 0=> if(st='0')then
ns<=0;
else
ns<=1;
sh<='1';
end if;
when 1 to 6 => sh<='1';
ns<= ps+1;
when 7=> sh<='1';
ns <=0;
end case;
end process;
process(clk)
begin
if(clk 'event and clk ='1')then
ps <= ns;
ci<= ciplus;
end if;
if(sh='1') then
C<=si & A(7 downto 1) ;
D<=B(0) & B(7 downto 1);
end if;
end process;
acc<= C;
end Behavioral;
`
Your second process is written incorrectly. Prior to writing a process, you should always decide whether the process is sequential or combinatorial, and then write the process accordingly.
To help you write your code, especially when starting out with hardware description languages, please please please always draw a block diagram first, and then describe that block diagram using VHDL.
As it is, your second process:
Mixes combinatorial and sequential logic.
Is missing signals in the process sensitivity list.
Generates a latch because C and D are not assigned in all paths through the process.
Your first process has similar problems.
try initializing ps and ns see if that does the trick I am on my phone now so i cant simulate to help but usualy my problems in VHDL design are form uninitilized integers
signal ps,ns: integer range 0 to 7:=0;
you might want to check your warnings list see if that helps
I am doing something like this:
x : in STD_LOGIC_VECTOR(15 downto 0);
signal x_d: std_logic_vector(15 downto 0);
type inp_concat_array is array (0 to 15) of std_logic_vector(1 downto 0);
signal inp_concat : inp_concat_array;
process (clk, reset)
begin
if (rising_edge(clk)) then
if (reset = '1') then
for i in 0 to 15 loop
x_d(i) <= '0';
end loop;
else
for i in 0 to 15 loop
x_d(i) <= x(i);
end loop;
end if;
end if;
end process;
for j in 0 to 15 loop
inp_concat(j) <= x(j) & x_d(j);
end loop;
Xilinx ISE 14.2 gives following errors
Syntax error near "for"
Syntax error near "loop"
Can i use asynchronous assignments in FOR loop?
The concurrent for loop must be made with a generate statement like:
inp_concat_loop : for j in 0 to 15 generate
inp_concat(j) <= x(j) & x_d(j);
end generate;
or in a process as described in David Koontzs answer.
Without seeing an entire design description answering your question could be a bit risky. You present us with a code fragment and no line numbers for the syntax error. The code fragment contains three for loops.
Now if this fragment represents a continuous segment extracted from a design unit (an architecture) it would appear that you are trying to use a loop statement (the for loop, a sequential statement appropriate for a process or subprogram) in a place appropriate for a concurrent statement (the architecture body).
Providing missing bits for something that might analyze:
library ieee;
use ieee.std_logic_1164.all;
entity asyn is
port (
x : in STD_LOGIC_VECTOR(15 downto 0);
clk: in std_logic;
reset: in std_logic
);
end entity;
architecture foo of asyn is
signal x_d: std_logic_vector(15 downto 0);
type inp_concat_array is array (0 to 15) of std_logic_vector(1 downto 0);
signal inp_concat : inp_concat_array;
begin
process (clk, reset)
begin
if (rising_edge(clk)) then
if (reset = '1') then
for i in 0 to 15 loop
x_d(i) <= '0';
end loop;
else
for i in 0 to 15 loop
x_d(i) <= x(i);
end loop;
end if;
end if;
end process;
for j in 0 to 15 loop
inp_concat(j) <= x(j) & x_d(j);
end loop;
end architecture;
And using a different tool yields:
ghdl -a async.vhdl
async.vhdl:32:5: a generate statement must have a label
async.vhdl:32:22: 'generate' is expected instead of 'loop'
In a place appropriate for a concurrent statement in an architecture body the only statement that can have a for keyword is a generate statement, which requires a label.
There is no requirement in VHDL to look ahead to disambiguate syntax errors (which is why you have a vague error message).
A different tool provides a bit better illustration:
nvc -a async.vhdl
** Error: syntax error, unexpected for, expecting process
File async.vhdl, Line 32
for j in 0 to 15 loop
^^^
So if you put the for loop in a process instead it just might analyze:
NEW_PROCESS:
process (x,x_d)
begin
for j in 0 to 15 loop
inp_concat(j) <= x(j) & x_d(j);
end loop;
end process;
Below is a suggestion for a simpler, neater solution. Simulation results follow.
-----------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------------
entity test is
port (
clk, reset: in std_logic;
x: in std_logic_vector(15 downto 0);
--test signals:
test: out std_logic_vector(1 downto 0);
test_index: in natural range 0 to 15);
end entity;
-----------------------------------------------
architecture test of test is
signal x_d: std_logic_vector(15 downto 0);
type inp_concat_array is array (0 to 15) of
std_logic_vector(1 downto 0);
signal inp_concat: inp_concat_array;
begin
process (clk, reset)
begin
if rising_edge(clk) then
if reset = '1' then
x_d <= (others => '0');
else
x_d <= x;
end if;
end if;
end process;
gen: for i in 0 to 15 generate
inp_concat(i) <= x(i) & x_d(i);
end generate;
test <= inp_concat(test_index);
end architecture;
-----------------------------------------------
The problem is that your asynchronous for loop is not inside a process, and needs to be: This should do it
process(x,x_d)
begin
for j in 0 to 15 loop
inp_process(j) <= x(j) & x_d(j);
end loop;
end process;
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- use ieee.std_logic_arith.all;
-- use ieee.numeric_std.all;
-- entity part contain R for output of Register
entity register_16 is
port( input: in std_logic_vector(15 downto 0);
ld, inc, clk, clr: in std_logic;
R: buffer std_logic_vector(15 downto 0));
end register_16 ;
-- it have to parallel process
architecture behavioral of register_16 is
begin
reg: process (input, ld, clk, clr)
variable R_temp: std_logic_vector(15 downto 0);
begin
if (clr = '1') then
R_temp := b"0000000000000000";
elsif (clk'event and clk = '1') then
if (ld = '1') then
R_temp := input;
end if;
end if;
R <= R_temp;
end process reg;
-- my error in this step
inc_R: process (inc)
begin
R <= R + '1';
end process inc_R;
end behavioral;
Main process (reg) works correctly, but other process has error adding 1.
You will have to convert the vector to an integer an back again, here's an example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
signal in : std_logic_vector( 7 downto 0 );
signal out : std_logic_vector( 7 downto 0 );
out <= std_logic_vector(to_unsigned(to_integer(unsigned( in )) + 1, 8));
For a good picture about type conversion take a look here:
http://www.bitweenie.com/listings/vhdl-type-conversion/
Sorry to say, but there are quite a lot of things wrong with your code...
You are mixing combinatorial and sequential code in the same process, which is poor coding style. If coded correctly, there really is no need for the variable R_temp.
The sensitivity list is a simulation aid only, yet you are trying to use it as a conditional (when inc changes, increment R). This will not work in hardware. When starting out with VHDL, my suggestion is to use VHDL_2008 and always use process(all) as the sensitivity list. This avoids beginner errors, since it reflects what synthesis does.
You are creating a combinatorial loop in the second process. This will not show up in simulation because of 2. above, but will cause errors in synthesis.
As already mentioned by baldyHDL, you are assigning to R in multiple processes.
Prefer unsigned to std_logic_vector when dealing with numbers. Generally you should not include std_logic_arith, nor std_logic_unsigned, just std_logic_1164 and numeric_std.
Adding a std_logic value (such as '1') is not standard, or at least not supported by all tools. Simply use an integer instead: R <= R + 1;
By your code, I gather that you are trying to write a counter with increment, load and clear signals. I don't just want to give you the code (that would ruin the learning experience for you), but try to fit the entire counter into a single process, using the following template:
process(clk) begin
if(rising_edge(clk)) then
-- Your code here vvv
if(clr = '1') then
elsif(ld = '1') then
elsif(inc = '1') then
end if;
-- Your code here ^^^
end if;
end process;
you write R in both of your processes. this leads to a multi-driver situation that is not possible to synthesise. to solve it, combine the processes, e.g.:
reg: process (clk, clr)
variable R_temp : std_logic_vector(15 downto 0);
begin
if (clr='1') then
R_temp := b"0000000000000000";
elsif (clk'event and clk='1') then
if (ld='1') then
R_temp := input;
elsif (inc='1') then
R_temp := R_temp + '1';
end if;
end if;
R <= R_temp;
end process reg;
You should be able to add a vector containing the value 1 as this, as you are using the numeric_std library:
R <= R + x"0001";
I used the following libraries and it was able to do something similar
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
signal cnt : std_logic_vector(3 downto 0);
begin
process(clk, reset, ce, cnt)
begin
if(reset = '1') then
cnt <= "0000";
elsif(clk'event and clk='1') then
if(ce='1') then
if(cnt = "1001") then
cnt <= "0000";
else
cnt <= cnt + 1;
I have written 2 state machines in my VHDL code. The simulation works fine, but the code does not synthesize. Any help would be appreciated. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pulse_width is
Port ( clk : in STD_LOGIC;
timer2:in std_logic;
input: in STD_LOGIC;
result: inout STD_LOGIC_VECTOR (15 downto 0);
SEL_LINE: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
data_out: out STD_LOGIC_VECTOR (23 downto 0):=x"000000");
end pulse_width;
architecture Behavioral of pulse_width is
TYPE count_states is (s0,s0_dash,s1,s2,s3,s1_dash);
SIGNAL current_state, next_state : count_states := s0 ;
TYPE write_states is (ws0,ws0_dash,ws1,ws2,ws3,ws4);
SIGNAL current_state1, next_state1 : write_states := ws0 ;
TYPE index_array is ARRAY(integer range 0 to 65535) of std_logic_vector(15 downto 0);
SIGNAL mem: index_array;
SIGNAL count: std_logic_vector(15 downto 0):=x"0000";
SHARED VARIABLE j: integer:=0;
SHARED VARIABLE a,i: integer:=1;
SIGNAL flag,push_data,push_first,push_final,push_pulses,rw_first,rw_end: std_logic:='0';
SIGNAL y_clk_input ,y_clk_timer2, enable_count: std_logic:='0';
SIGNAL first,final: std_logic_vector(15 downto 0):= x"0001";
begin
-- Pulse width count
process (clk)
begin
if rising_edge(clk) then
current_state<=next_state;
current_state1<=next_state1;
end if;
end process;
process(input,SEL_LINE,current_state)
begin
------------------------------------------------------------------------
case current_state is
when s0 =>
if(input='1') then
next_state<=s1;
else
next_state<=s0;
end if;
when s1 =>
flag<='0';
if input='1' then
count <= count+ x"0001";
next_state<=s1_dash;
else
next_state<=s2;
end if;
when s1_dash =>
if input='1' then
count <= count+ x"0001";
next_state<=s1;
else
next_state<=s2;
end if;
when s2 =>
result <= count;
next_state<=s3;
when s3=>
count <= x"0000";
next_state<=s0;
enable_count<='0';
when others =>
next_state<=s0;
end case;
--------------------------------------------------------------------------
case current_state1 is
when ws0 =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0_dash;
end if;
when ws0_dash =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0;
end if;
when ws1=>
if rw_first='1' and rw_end='1' then
next_state1<=ws0;
else
mem(a) <= result;
a:=a+1;
final<=final+x"0001";
next_state1<=ws2;
end if;
when ws2 =>
next_state1<=ws0;
result<=x"0000";
when others =>
next_state1<=ws0;
end case;
end process;
I eventually need to implement three state machines.
The math you're trying to do in the asynchronous state logic is not registered and won't synthesize well. You need to re-arrange your state logic so statements like:
count <= count+ x"0001";
...
final<=final+x"0001";
...are synchronous and not 'free running' in an asynchronous loop.
The problem is that you read and write the same signals in one combinational process.
Either put everything in one clocked (synchronous) process
Or: use explicit registers: count_next <= count + x"0001";
Not related to your error, but still worth paying attention to:
You have a ton of unused signals and shared variables:
push_data,push_first,push_final,push_pulses, y_clk_input ,y_clk_timer2, first, i,j
This is confusing for anybody trying to read your code. 1
The packages STD_LOGIC_arith and STD_LOGIC_unsigned are deprecated