I have this code for a Serial Adder in VHDL. I am trying to get it to work, but I keep on getting an error that says:
Errors found in VHDL File -
Line : 17, Error : Index constraint expected in the subtype indication
This error is referring to the line:
signal state, next_state : integer range 0 to 3;
I'm not sure why this is happening. Any help? Please find the full code below.
library ieee;
use ieee.std_logic_1164.all;
entity adder is
port(
start : in std_logic;
clk : in std_logic;
a_out : out std_logic_vector(3 downto 0)
);
end adder;
architecture behave of adder is
signal a, b : std_logic_vector(3 downto 0);
signal shift : std_logic;
signal Cin, Cout : std_logic;
signal sum_in : std_logic;
signal state, next_state : integer range 0 to 3;
begin
sum_in <= a(0) xor b(0) xor Cin;
Cout <= (Cin and a(0))or(Cin and b(0))or(a(0) and b(0));
a_out <= a;
process(state, start)
begin
case state is
when 0 =>
if start = '1' then shift <= '1'; next_state <= 1;
else shift <= '0'; next_state <= 2; end if;
when 1 => shift <= '1'; next_state <= 2;
when 2 => shift <= '1'; next_state <= 3;
when 3 => shift <= '1'; next_state <= 0;
end case;
end process;
process(clk)
begin
if clk'event and clk = '0' then
state <= next_state;
if shift = '1' then
a <= sum_in & a(3 downto 1);
b <= b(0) & b(3 downto 1);
Cin <= Cout;
end if;
end if;
end process;
end behave;
Try to replace your line in which you are getting error by:
signal state, next_state : integer is range 0 to 3;
If you are specifying range then you should use is range instead of range
Related
I'm sending data to and A/D converter and I need the command data to be delayed at least 50ns from clk_19khz. Here is what I have so far.
How do I insert a delay of 50ns which is a requirement for the A/D between the clk_19khz and my first Dout bit to the A/D?
I'm using a Xilinx FPGA. Thanks for the help!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity PSOL is
Port ( clk : in STD_LOGIC;
clk_19khz : OUT std_logic;
Dout :out std_logic);
end PSOL;
architecture Behavioral of PSOL is
signal temp : std_logic;
signal count : integer range 0 to 1301 := 0; --1301
signal temp2 : std_logic;
signal dcount : integer range 0 to 11 := 0; --
signal start : std_logic := '1'; -- indicates the start of
signal parity : std_logic := '1'; --used to varify data sent
signal stop : std_logic := '0'; --indicate when word/command has
--signal chip_select : bit :='1'; -- active low
begin
process (clk)
begin
if (clk' EVENT AND clk='1') then
if (count = 1301) then --1301
temp <= not(temp);
count <=0;
else
count <= count + 1;
end if;
end if;
end process;
clk_19khz <= temp;
temp2 <= temp;
process (temp2)
begin
If (temp2' EVENT and temp2 ='0') then
dcount <= dcount + 1;
parity <= '1';
stop <= '0';
start <='1';
if (dcount < 12 and start = '1' and stop = '0') then
CASE dcount is
when 1 => Dout <= start; -- need delay 50ns before this
when 2 => Dout <= '0';
when 3 => Dout <= '1';
when 4 => Dout <= '0';
when 5 => Dout <= '1';
when 6 => Dout <= '0';
when 7 => Dout <= '0';
when 8 => Dout <= '1';
when 9 => Dout <= '1';
when 10 => Dout <= parity;
when 11 => Dout <= '0';
when others => null;
end case;
end if;
end if;
--dcount <= 0;
--start <='1';
end process;
end Behavioral;
Your clock (50 MHz) has a period of 20 ns. So you'll need a modulo-3 counter to count a delay of at least 3 clock pulses which gives a delay of 60 ns.
Declarations:
signal delay_en : std_logic;
signal delay_us : unsigned(1 downto 0) := (others => '0');
signal delay_ov : std_logic;
Usage:
process(clk)
begin
if rising_edge(clk) then
if (delay_en = '1') then
delay_us <= delay_us + 1;
else
delay_us <= (others => '0');
end if;
end if;
end process;
delay_ov <= '1' when (delay_us = 2) else '0';
Your current implementation needs to drive delay_en while it's waiting for the timespan. If the delay is over, it emits the signal delay_ov (ov = overflow). This can be used by your solution to go on the in algorithm. Your code should also deassert delay_en, what clears the counter to 0.
I have some troubles with my nexys 3 vhdl driver for the Pmod TMP. I would like to communicate with via SPI 3 wire (Clock, Reset and DQ (MISO/MOSI)) so I've wrote some code lines and test it using the leds to display receive data. But That don't work and I don't know why... I've made a state machine that, if it's the first time, send the configuration data and then send the word "start" to start convert, then I pass in receive configuration and take the convert data (temperature in binary) and finally send the "stop" word. And that start again without the send configuration because it's not the first time.
My state machine don't work, there is not receive data and I don't know why.
I'll be glad if you could help me.
Best regards.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SPI is
port(
CLK : in std_logic;
RST : in std_logic;
SPI_SCK : out std_logic;
SPI_DQ: inout std_logic;
SPI_RST : out std_logic;
LED : out std_logic_vector(7 downto 0) :="00000000"
);
end entity SPI;
architecture behavioral of SPI is
type State is ( IDLE , sendConf, sendBit , receiveBit, clockHigh , resetHigh);
signal States : State := IDLE;
signal Counter : integer range 0 to 15 := 0;
signal data_reg : std_logic_vector(15 downto 0):="0000000000000000";
signal data : std_logic_vector(8 downto 0):="000000000";
signal data_trans : std_logic_vector(7 downto 0):="00000000";
signal first_time : std_logic := '1';
signal send : std_logic := '0';
signal receive : std_logic := '0';
signal right : std_logic := '0';
begin
process(CLK, RST)
variable conf : std_logic_vector(15 downto 0):= "0000110000000011";
variable start: std_logic_vector(7 downto 0):= "01010001";
variable stop : std_logic_vector(7 downto 0):= "00100010";
begin
if rising_edge(CLK) then
if RST = '1' then
States <= IDLE;
first_time <= '1';
else
case States is
when IDLE =>
SPI_RST <= '1';
SPI_SCK <= '0';
Counter <= 0;
if first_time = '1' then
data_reg <= conf;
send <= '1';
first_time <= '0';
States <= sendConf;
else
if send = '1' then
data_trans <= start;
send <= '0';
receive <= '1';
right <= '0';
States <= sendBit;
elsif receive = '1' then
receive <= '0';
right <= '1';
States <= receiveBit;
elsif send = '0' and receive = '0' then
data_trans <= stop;
send <= '1';
right <= '0';
States <= sendBit;
end if;
end if;
when sendConf =>
SPI_SCK <= '0';
SPI_DQ <= data_reg(15);
data_reg <= data_reg(14 downto 0) & "0";
States <= clockHigh;
when sendBit =>
SPI_SCK <= '0';
SPI_DQ <= data_trans(7);
data_trans <= data_trans(6 downto 0) & "0";
States <= clockHigh;
when receiveBit =>
SPI_SCK <= '0';
data <= data(7 downto 0) & SPI_DQ;
States <= clockHigh;
when clockHigh =>
SPI_SCK <= '1';
if first_time = '1' then
if Counter = 16 then
States <= resetHigh;
else
Counter <= Counter + 1;
States <= sendConf;
end if;
else
if right = '1' then
if Counter = 9 then
States <= resetHigh;
else
Counter <= Counter + 1;
States <= sendBit;
end if;
else
if Counter = 8 then
States <= resetHigh;
else
Counter <= Counter + 1;
States <= sendBit;
end if;
end if;
end if;
when resetHigh =>
SPI_RST <= '0';
States <= IDLE;
end case;
end if;
end if;
end process;
end architecture behavioral;`
The Maxim DS1626 does not communicate via SPI interface. So please look into data sheet pages 4, 5 and 10, 11. These timing diagrams are very different from SPI or I²C or whatever.
I've written code for a binary divider that takes in an 8 bit dividend, 3 bit divisor, and gives a 5 bit quotient (3 bit remainder). I've literally spent hours trying to fix a bug that gives incorrect results but I haven't been able to identify it. Any help would be GREATLY appreciated! I basically get wrong answers for my inputs but I can't figure out why. There is a bus that takes in values and on the first clock cycle where st is 1, the dividend register is loaded. On the second clock cycle after, the divisor register is loaded and the calculation is made for the next three clock cycles.
The V signal is the output to signify that an overflow has occured (the result can't be fit into the five bits of the quotient), my st is the start signal to start the process, sh is the shift signal for the shift register, su is the subtract signal for the subtractor.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Divider is
Port (bus_in: in std_logic_vector(8 downto 0);
St, Clk, reset: in std_logic;
Quotient: out std_logic_vector(4 downto 0);
Remainder: out std_logic_vector(2 downto 0);
v: out std_logic);
end Divider;
architecture Behavioral of Divider is
signal State, NextState: integer range 0 to 5;
signal C, Ld1, Ld2, Su, Sh: std_logic;
signal Divisor: std_logic_vector(2 downto 0);
signal Subout: std_logic_vector(3 downto 0);
signal Dividend: std_logic_vector(8 downto 0);
begin
Subout <= Dividend(8 downto 5) - ('0' & divisor);
C <= not Subout (3);
Remainder <= Dividend(7 downto 5);
Quotient <= Dividend(4 downto 0);
State_Graph: process (State, St, C)
begin
Ld1 <= '0';
Ld2<='0';
v <= '0';
Sh <= '0';
Su <= '0';
case State is
when 0 =>
if (St = '1') then
Ld1 <= '1';
NextState <= 1;
else
NextState <= 0;
end if;
when 1 =>
if (St = '1') then
Ld2 <= '1';
NextState <= 2;
else
Ld2<='1';
NextState <= 2;
end if;
when 2 =>
if (C = '1') then
v <= '1';
NextState <= 0;
else
Sh <= '1';
NextState <= 3;
end if;
when 3 | 4 =>
if (C = '1') then
Su <= '1';
NextState <= State;
else
Sh <= '1';
NextState <= State + 1;
end if;
when 5 =>
if (C = '1') then
Su <= '1';
end if;
NextState <= 0;
end case;
end process State_Graph;
Update: process (Clk)
begin
if Clk'event and Clk = '1' then
State <= NextState;
--if Load = '1' then
-- Dividend <= '0' & bus_in;
--end if;
if Ld1 = '1' then
Dividend <= '0'&Bus_in(7 downto 0);
end if;
if Ld2 = '1' then
Divisor <= Bus_in(2 downto 0);
end if;
if Su = '1' then
Dividend(8 downto 5) <= Subout;
Dividend(0) <= '1';
end if;
if Sh = '1' then --94
Dividend <= Dividend(7 downto 0) & '0';
end if;
end if;
end process update;
end Behavioral;
Here's my input and outputs:
[Signals]: http://imgur.com/fqfiYJZ 1
The picture shows that my registers for the divisor and dividend is loading correctly. So I think the issue is with the actual division code. The state machine also seems to be working correctly.
Don't write this yourself. You are re-inventing the wheel.
Either write q <= a / b;
or use an IP core from your FPGA vendor.
I am a newbie when it comes to VHDL, but i am working on a counter than can manually count up and down by the push of a button.. Somehow i am only getting this error, and i dunno what i am doing wrong, all other checks are good. any suggestion?
This is the error i get:
ERROR:Xst:827 - line 101: Signal s2 cannot be synthesized, bad synchronous description.
The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
entity updown is Port (
rst : in STD_LOGIC;
plus , plusin: in STD_LOGIC;
minus, minusin : in STD_LOGIC;
clk : in STD_LOGIC;
ud_out, ud_out2 : out STD_LOGIC_VECTOR (3 downto 0)
);
end updown;
architecture Behavioral of updown is
signal s : unsigned (3 downto 0):= "0000";
signal s2 : unsigned (3 downto 0) := "0000";
begin
process(rst, plus, minus, clk, plusin, minusin)
begin
if rst='1' then
s <= "0000";
s2 <= "0000";
else
if rising_edge (clk) then
if plus ='1' or plusin = '1' then
if s = "1001" then
s <= "0000";
if s2 = "1001" then
s2 <= "0000";
else
s2 <= s2 + 1;
end if;
else
s <= s + 1;
end if;
end if;
else
if minus ='1' or minusin = '1' then
if s = "0000" then
s <= "1001";
if s2= "0000" then
s2 <= "1001";
else
s2 <= s2 - 1;
end if;
else
s <= s - 1;
end if;
end if;
end if;
end if;
end process;
ud_out <= std_logic_vector(s);
ud_out2 <= std_logic_vector(s2);
end Behavioral;
Your description of a synchronous process is flawed. A synchronous process has events that update only on the edge of a clock signal (although in this case there is an also an asynchronous reset behaviour )
Your sensitivity list contains more than it needs to describe a synchronous process.
Replace
process(rst, plus, minus, clk, plusin, minusin)
with
process(rst, clk )
signals will then only update when the clock transisitions, or rst changes.
Some compilers are even more picky, and might require you to change
else if rising_edge (clk)then
to
elsif rising_edge(clk) then
EDIT:
This should work. I've layed it out clearly so its actually easy to follow what's going on. I'd suggest you do the same in future. It make simple closure errors easy to spot
entity updown is
port (
signal clk : in std_logic;
signal rst : in std_logic;
signal plus : in std_logic;
signal plusin : in std_logic;
signal minus : in std_logic;
signal minusin : in std_logic;
signal ud_out : out std_logic_vector(3 downto 0);
signal ud_out2 : out std_logic_vector(3 downto 0)
);
end entity updown;
architecture behavioral of updown is
signal s : unsigned (3 downto 0);
signal s2 : unsigned (3 downto 0);
begin
p_counter_process: process(rst, clk)
begin
if rst ='1' then
s <= (others => '0');
s2 <= (others => '0');
elsif rising_edge(clk) then
if plus ='1' or plusin = '1' then
if s = "1001" then
s <= "0000";
if s2 = "1001" then
s2 <= "0000";
else
s2 <= s2 + 1;
end if;
else
s <= s +1;
end if;
end if;
-- you had a mismatched end if statement here. Removed
if minus ='1' or minusin = '1' then
if s = "0000" then
s <= "1001";
if s2= "0000" then
s2 <= "1001";
else
s2 <= s2 - 1;
end if;
else
s <= s - 1;
end if;
end if;
end if;
end process;
ud_out <= std_logic_vector(s);
ud_out2 <= std_logic_vector(s2);
end architecture;
I am new to VHDL. I need to write a module to do filtering of data. My module structure is:
a_rst - async reset
clk - clock
s_rst - sync reset
valid_in - 0 - no data, 1 - where is data
data_in - [7 downto 0]
Out signals:
valid_out - 0 - no data, 1 - where is data
data_out - [7 downto 0]
I write testbeanch which puts to data_in of my module: 00,01,02,03,0A,02,00,01,02,0F.
But my module returns: 00,01,AA,03,0A,02,00,01,AA,0F
insted of: 00,01,AA,03,0A,02,00,01,02,0F.
I tried to do this:
--libraries
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--entity
entity ex6_v03 is
port
(
a_rst : in std_logic;
clk : in std_logic; -- 200 MHz
s_rst : in std_logic;
valid_in : in std_logic;
data_in : in std_logic_vector (7 downto 0);
valid_out : out std_logic;
data_out : out std_logic_vector (7 downto 0)
);
end entity ex6_v03;
architecture behavior of ex6_v03 is
signal st : integer := 0;
begin
process(a_rst, clk)
begin
-- asynchronous reset
if (a_rst = '1') then
data_out <= x"00";
valid_out <= '0';
-- synchronous reset
elsif rising_edge(clk) then -- clk
if (s_rst = '1') then
valid_out <= '0';
data_out <= x"00";
else
-- normal activity
if(valid_in = '1') then
-- main logic
if(data_in = x"00") then
st <= 1;
valid_out <= '1';
data_out <= data_in;
elsif(st = 1 and data_in = x"01") then
st <= 2;
valid_out <= '1';
data_out <= data_in;
elsif(st = 2 and data_in = x"02") then
st <= 3;
valid_out <= '1';
data_out <= x"AA";
elsif(st = 3 and data_in = x"03") then
valid_out <= '1';
data_out <= data_in;
st <= 0;
else
st <= 0;
valid_out <= '1';
data_out <= data_in;
end if;
-- end main logic
else
valid_out <= '0';
data_out <= x"00";
end if;
end if;
end if;
end process;
end architecture behavior;
But my module do not wait for 0x03 and instantly sends 0xAA. How to fix this?
You need to add a 1 clock cycle buffer so you know if the next input is 03 before you choose whether to send 02 or AA. Of course, this means the output wont appear until 2 cycles after the input instead of only one. See revised code:
--libraries
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--entity
entity ex6_v03 is
port
(
a_rst : in std_logic;
clk : in std_logic; -- 200 MHz
s_rst : in std_logic;
valid_in : in std_logic;
data_in : in std_logic_vector (7 downto 0);
valid_out : out std_logic;
data_out : out std_logic_vector (7 downto 0)
);
end entity ex6_v03;
architecture behavior of ex6_v03 is
signal st : integer := 0;
signal bvalid : std_logic := '0'; --is buffer valid?
signal data_buffer : std_logic_vector (7 downto 0); --data from previous cycle
begin
process(a_rst, clk)
begin
if (a_rst = '1') then -- asynchronous reset
data_out <= x"00";
valid_out <= '0';
bvalid <= '0';
elsif rising_edge(clk) then -- clk
if (s_rst = '1') then --sync reset
valid_out <= '0';
bvalid <= '0';
data_out <= x"00";
else -- normal activity
if(valid_in = '1') then --fill buffer
if(data_in = x"00") then
st <= 1;
data_out <= data_in;
elsif(st = 1 and data_in = x"01") then
st <= 2;
data_out <= data_in;
elsif(st = 2 and data_in = x"02") then
st <= 3;
else
st <= 0;
end if;
data_buffer <= data_in;
bvalid <= '1';
else
bvalid <= '0';
end if;
if(bvalid = '1') then --use buffer to populate output
valid_out <= '1'
if(st = 3 and data_in = x"03" and valid_in = '1') then --EDIT: make sure the x"03" sitting on the input is actually valid
data_out <= x"AA"; --output for the previous cycle (buffer contains x"02")
else
data_out <= data_buffer;
end if
else
valid_out <= '0';
data_out <= x"00";
end if;
end if;
end if;
end process;
end architecture behavior;