- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi. I'm new to VHDL and I thought I could try to make a slave SPI device as training, but it's not working quite as expected. Below my current code. It's compiles and upload just fine, but it's not working as intended. Right now I have the leds connected to the signal "bitnumber", bitnumber is supposed to increment on each rising edge of CLK and then reset to zero when the SS pin is pulled LOW (indicating that the transfer is complete), but it doesn't do that. I've connected my Altera DE0-nano to my arduino which is simply pulling the SS LOW, sends four clock pulses and then pulls the SS back high, I've put a 1s delay between each transition. The leds on my altera board does change it's pattern every second, but it does so on both rising and falling edge of the clock, also the led pattern seems completely random, even showing some leds in a dimmed state. The leds become black when the SS pin goes back HIGH though, that's good.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SPI2 is
PORT (LED : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
GPIO_0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0));
end SPI2;
architecture SPI2_beh of SPI2 is
signal SPIdataregister : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal bitnumber : STD_LOGIC_VECTOR(7 DOWNTO 0);
begin
LED <= bitnumber;
process(GPIO_0(5), GPIO_0(3))
begin
if ((GPIO_0(5)) = '1') then
bitnumber <= (bitnumber + '1');
end if;
if ((GPIO_0(3)) = '1') then
bitnumber <= "00000000";
end if;
end process;
process(bitnumber)
begin
case bitnumber is
when "00000001" => SPIdataregister(0) <= GPIO_0(7);
when "00000010" => SPIdataregister(1) <= GPIO_0(7);
when "00000011" => SPIdataregister(2) <= GPIO_0(7);
when "00000100" => SPIdataregister(3) <= GPIO_0(7);
when "00000101" => SPIdataregister(4) <= GPIO_0(7);
when "00000110" => SPIdataregister(5) <= GPIO_0(7);
when "00000111" => SPIdataregister(6) <= GPIO_0(7);
when "00001000" => SPIdataregister(7) <= GPIO_0(7);
when others => SPIdataregister <= SPIdataregister;
end case;
end process;
end SPI2_beh;
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The main problem with your code is that it isn't synchronous. A VHDL simulator may simulate your code correctly because it will only execute the first process when one of your GPIO signals will change, but a VHDL synthesizer will not know what to do with your code.
I suggest to use a clock and make the first process a regular clocked process. The DE0 kit should have an on-board oscillator that you can use. Then you will need to change your process a bit. The part with the reset pin can be used as is, but for the clock signal you will need to detect a rising edge. The recommended way of doing that is to create an extra signal that will hold the previous value of GPIO_0(5). Then if that signal is '0' and GPIO_0(5) is '1', it means you have a rising edge and you can increase bitnumber. Also it isn't recommended to use IEEE.STD_LOGIC_UNSIGNED.ALL because it isn't a standard library, and it will cause problems if you try to mix unsigned and signed values, or try to use other libraries. The recommended way is to use IEEE.NUMERIC_STD.ALL instead, and make your bitnumber an "unsigned" type instead of "std_logic_vector". You can use the rest of the code as is, except for LED, as you will need to cast bitnumber back to the vector type:LED <= std_logic_vector(bitnumber);

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page