I am learning VHDL and for first project I picked up simple Brainfuck processor. When I try to compile it, I get error about incompatibile slices. I am using EdWinXP. How do I fix my code? Are there many mistakes in my code? Is there alternative of VHDL that would be simpler for C programmer?
use ieee.std_logic_1164.all;
entity BFCPU is
port (
I0 : in std_logic; --INPUT
I1 : in std_logic; --PROGRAM
I2 : in std_logic; --PROGRAM READY
O1 : out std_logic; --PROGRAM NEEDED
O2 : out std_logic; --OUTPUT
O3 : out std_logic; --OUTPUT WRITTEN
O4 : out std_logic); --INPUT NEEDED
--O5 : out std_logic); --INPUT POOLING CLOCK
end BFCPU;
architecture work of BFCPU is
type t_Memory is array (0 to 127) of std_logic_vector(7 downto 0);
signal rammem : t_Memory;
signal pointer : std_logic;
begin
pointer <= 0;
workflow: process (I2) is
begin
if I1=1 then
rammem(pointer) <= std_logic_vector(unsigned(rammem(pointer)) + 1);
elsif I1=2 then
rammem(pointer) <= std_logic_vector(unsigned(rammem(pointer)) - 1);
elsif I1=3 then
pointer <= pointer - 1;
elsif I1=4 then
pointer <= pointer + 1;
elsif I1=5 then
O2 <= rammem(pointer);
elsif I1=6 then
O4 <= not O4;
inwait: while( I0 = 0 ) loop
if not (I0 = 0) then
rammem(pointer) <= I0;
end if;
end loop inwait;
O4 <= not O4;
end if;
end process workflow;
end work;
What you're writing below the begin statement and outside a process is always true, so this isn't sequential in any form. Imagine like an FPGA pin, which is soldered to ground.
You try to manipulate the pointer signal from within a process, but you can't because your pointer is fixed to '0'.
If you want the pointer initializing to '0', as it looks like, you have to put this line within the process. However, i see you try to call arithmetic operations with the pointer signal, but you are defining the signal as std_logic. std_logic can represent '0', '1' and several other states, like High-Z, but not a number. You should take an integer or natural for calculations.
Related
So I've been working on some homework for my VHDL course and I can't seem to understand this problem.
The point here is to create the adder/subtractor of an ALU that works both on 2's complement and unsigned 32-bit buses, which is why I have a condition called sub_mode ( A - B = A + !B + 1 ) which will also be the carry-in when activated.
The rest of the different inputs and outputs are pretty self-explanatory.
My problem is with the testbenching of such component where, even though carry_temp and r_temp have been initialized in declaration section of the architecture, end up showing up undefined. I have guessed that it is due to the for loop within the process screwing everything up. Would that be an accurate guess? And if yes, is it possible to proceed to add two bit buses together without having to fully create an n-bit adder made from n 1-bit adder components?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity add_sub is
port(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
sub_mode : in std_logic;
carry : out std_logic;
zero : out std_logic;
r : out std_logic_vector(31 downto 0)
);
end add_sub;
architecture synth of add_sub is
signal cond_inv : std_logic_vector(31 downto 0);
signal carry_temp : std_logic_vector(32 downto 0) := (others => '0');
signal r_temp : std_logic_vector(31 downto 0) := (others => '0');
begin
behave : process(a,b,sub_mode)
begin
if sub_mode = '1' then
cond_inv <= b xor x"ffffffff";
else
cond_inv <= b;
end if;
carry_temp(0) <= sub_mode;
for i in 0 to 31 loop
r_temp(i) <= a(i) xor cond_inv(i) xor carry_temp(i);
carry_temp(i+1) <=
(a(i) and cond_inv(i)) or
(a(i) and carry_temp(i)) or
(cond_inv(i)and carry_temp(i));
end loop;
if r_temp = x"00000000" then
zero <= '1';
else
zero <= '0';
end if;
r <= r_temp;
carry <= carry_temp(32);
end process behave;
end synth;
I am trying to increment and decrement with two push-buttons. The algorithm goes well but I have a little issue. Supposedly I am incrementing , when I try to decrement the accumulator it increments once more , and only after that it start
to decrement. Same if I try to decrement first. If it is someone to help me I will be very thankfully.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.std_logic_unsigned.all;
entity my_offset_controller is
port(clk : in std_logic;
input : in std_logic_vector(15 downto 0);
add_button : in std_logic;
sub_button : in std_logic;
output_res : out std_logic_vector(15 downto 0)
);
end my_offset_controller;
architecture Behavioral of my_offset_controller is
signal buttonState_up : std_logic:='0';
signal accumulator : std_logic_vector(15 downto 0);
signal lastButtonState_up : std_logic:='0';
signal buttonState_down : std_logic:='0';
signal lastButtonState_down : std_logic:='0';
signal buttonPushCounter : integer range 0 to 512 :=0;
process(clk)
begin
if rising_edge(clk) then
buttonState_up <= add_button;
buttonState_down <= sub_button;
if (buttonState_up /= lastButtonState_up) then
if (buttonState_up ='1') then
buttonPushCounter <= buttonPushCounter + 1;
accumulator <= std_logic_vector(to_unsigned(buttonPushCounter,accumulator'length));
end if;
lastButtonState_up <= buttonState_up;
elsif (buttonState_down /= lastButtonState_down) then
if (buttonState_down ='1') then
buttonPushCounter <= buttonPushCounter - 1;
accumulator <= std_logic_vector(to_unsigned(buttonPushCounter,accumulator'length));
end if;
lastButtonState_down <= buttonState_down;
end if;
end if;
end process;
output_res<= accumulator + input ;
This particularly module I use to controll the offset of an signal that I plot on an vga screen.
It's hard to help you without more information. You should provide a testbench with a chronogram to make it easier. Yet, by looking at your process I would say that the problem comes from the following lines:
buttonPushCounter <= buttonPushCounter + 1;
accumulator <= std_logic_vector(to_unsigned(buttonPushCounter,accumulator'length));
What you did there is increment buttonPushCounterat the same time that you update accumulator. This way buttonPushCounter will always be shifted by +1 or -1 depending on the last event.
What I can recommend is to update accumulator at every clock cycle instead of every time an event occurs. For example like this:
if rising_edge(clk) then
accumulator <= std_logic_vector(to_unsigned(buttonPushCounter,accumulator'length));
...
I'm trying to write VHDL code for a 3 input simple adder. When I type the following code, S gets the correct output value but S1 gets zero, and hence add_out also gets the wrong value.
library ieee;
use ieee.std_logic_1164.all;
entity adder is
port( A,B : in std_logic_vector(3 downto 0);
C : in std_logic;
carry_out : out std_logic;
S : out std_logic_vector(3 downto 0);
addOut : out std_logic_vector(4 downto 0));
end adder;
architecture behavioral of adder is
signal S1 : std_logic_vector(3 downto 0);
begin
proc : process(A,B,C) is
variable carry : std_logic;
begin
carry := C;
for i in 0 to 3 loop
S(i) <= A(i) xor B(i) xor carry;
S1(i) <= A(i) xor B(i) xor carry;
carry := (A(i) and B(i)) or (B(i) and carry) or (A(i) and carry);
end loop;
carry_out <= carry;
addOut <= carry & S1;
end process proc;
end behavioral;
Why is the signal S1 not getting the same value as S?
S1 probably (almost certainly) DOES get the same value as S.
However you wouldn't expect to see that value of S1 on addOut, thanks to the mistake in the process sensitivity list. Study the semantics of signal assignment, (aka "postponed assignment") and delta cycles, and all will become clear. (My usual explanation on this topic, if you'll excuse some self publicity)
Specifically, you have a new value on S1, but no means to wake up the process again to propagate it to any other signal.
The best fix is probably to move the addOut and carryOut assignments outside the process, where they will immediately reflect any changes on their own inputs, and reduce the likelihood of sim/synth mismatches.
I am trying to detect changes in the input signals of my Selector. When I find the first input that changed (either rising or falling edge), I give an index as output. When I try to synthesize my source code, I get an error "unsupported Clock statement". A also tried to use "rising_edge" and "falling_edge", but I got the same error.
Here is my code
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
begin
process(X1,X2,X3,X4,X5,X6)
begin
if (X1'event) then
O <= "000";
elsif (X2'event) then
O <= "001";
elsif (X3'event) then
O <= "010";
elsif (X4'event) then
O <= "011";
elsif (X5'event) then
O <= "100";
elsif (X6'event) then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
Is there an alternative solution for that?
You would need an additional clock input to make a comparison between the value of X1, X2, ... in the current clock cycle and the value in the last clock cycle. If the Xes are asynchronous to the clock you have to synchronize them first.
Input synchronisation
To synchronize the inputs to the clock, you have to sample each input with two D flip-flops in serial. The output of the first flip-flop may be harmed by metastability problems which is described in more detail in these papers:
Ran Ginosar: Metastability and Synchronizers: A Tutorial
Sunburst Design: Synthesis and Scripting Techniques for Designing Multi-
Asynchronous Clock Designs
The connection between both flip-flops (for each input) must be constrained so that the rounting path between them is as short as possible. The implementation below will just show the two flip-flops. A more advanced implementation can be found in the sync_Bits component of the PoC Library where I am one of the authors.
Comparison
Once the input is synchronous to the clock, just delay it another clock cylce. This will make up the last value, so that, you can compare the current values to the last values to detect a signal change. The frequency of the input clock must be much faster than the frequency of change on one of the X inputs:
to get a fast repsonse of the edge-detection, and
to catch all signal changes.
Here is a possible implementation:
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
clk : in std_logic;
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
signal X : std_logic_vector(6 downto 1); -- all inputs in one vector
signal X_meta : std_logic_vector(6 downto 1); -- first sampling stage
signal X_curr : std_logic_vector(6 downto 1); -- second sampling stage =
-- current value
signal X_last : std_logic_vector(6 downto 1); -- last value of X_curr
begin
-- Concatenate all inputs to one vector for shorter code below.
X <= X6 & X5 & X4 & X3 & X2 & X1;
-- Synchronize external inputs to clock. If the X* inputs are already
-- synchronous to 'clk' then replace this process with:
-- X_curr <= X;
sync: process(clk)
begin
if rising_edge(clk) then
-- The path betweeen these two flip-flops must be constrained for a
-- short delay, so that, the wire in between is as ahort as
-- possible.
X_meta <= X;
X_curr <= X_meta;
end if;
end process;
-- This statement delays the current value X_curr by one clock cycle.
X_last <= X_curr when rising_edge(clk);
-- Comparison and selector output.
process(X_curr, X_last)
begin
if (X_curr(1) xor X_last(1)) = '1' then
O <= "000";
elsif (X_curr(2) xor X_last(2)) = '1' then
O <= "001";
elsif (X_curr(3) xor X_last(3)) = '1' then
O <= "010";
elsif (X_curr(4) xor X_last(4)) = '1' then
O <= "011";
elsif (X_curr(5) xor X_last(5)) = '1' then
O <= "100";
elsif (X_curr(6) xor X_last(6)) = '1' then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
I have the following code for a structural modeling in VHDL. When I try to compile it (ghdl -a filename.vhdl), I get this error in the 4 lines commented below: "<=" or ":=" expected instead of port
BTW, I had already defined the components used before the code block below.
What's wrong with my code? Am I not allowed to use port map inside a process/if-statement?
What can I do to fix this? Thanks!
-- Entity Definition
entity jk is
port(
CP: in std_logic; -- clock signal
J : in std_logic; -- J signal
K : in std_logic; -- K signal
Q : inout std_logic; -- Q signal
QN : inout std_logic; -- Q' signal
reset : in std_logic -- reset signal
);
end entity jk;
architecture dev1 of jk is
-- declare the singals that outputs the results of some gates
signal a, b, internal_q, internal_qn : std_logic;
-- get each component needed
component and3 is
port(o0 : out std_logic; i0, i1, i2: in std_logic);
end component and3;
component nor2 is
port(o0 : out std_logic; i0, i1: in std_logic);
end component nor2;
begin
internal_q <= Q; -- used to show internal Q value
QN <= not Q; -- inverse of Q
internal_qn <= QN; -- used to show internal QN value
process is
begin
if (reset = '0') then -- asynchronous reset
Q <= '0';
internal_qn <= '0';
elsif rising_edge(CP) then -- on positive clock edge
-- AND gate outputs
g0: and3 port map(a, internal_q, K, CP); -- error
g1: and3 port map(b, internal_qn, J, CP); - error
-- NOR gate outputs
g2: nor2 port map(Q, a, internal_qn); -error
g3: nor2 port map(QN, b, internal_q); -error
end if;
end process;
end architecture dev2;
No, you are not allowed to instantiate components (use port maps) inside of a process.
You should be instantiating your components below the begin statement of your architecture. Wire them up there appropriately. Your process should drive all of the registered logic. I actually don't see any need for a process statement at all in this code. Since all of your inputs are coming from your entity (I assume) then you really don't need to do any registered logic in this file.
Can you post your entity as well? I cannot see where signals J and K and CP and Q and QN are being defined.