Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Fpga

Status
Not open for further replies.
Ok i know im posting alot here but figured out i can implement a internal signal to use instead of the actual pin. This way i can leave it as OUT and not INOUT and also not have to process it:

Code:
entity BlinkLed is
    Port ( LED_01 : out  STD_LOGIC;
           OSC_IN : in  STD_LOGIC;
			  RESET : in STD_LOGIC);	  
end BlinkLed;

architecture Behavioral of BlinkLed is
	signal state : std_logic;
begin
	
	process(OSC_IN, RESET) is begin
	
	if(RESET = '1') then
	  state <= '0';
	elsif(rising_edge(OSC_IN)) then
	  state <= not state; 
	end if; 
		
	end process;
	
	LED_01 <= state;

end Behavioral;

sim-jpg.55772


Im sure i can also use BIT instead of STD_LOGIC but heh its ok i assume
 

Attachments

  • sim.jpg
    sim.jpg
    23.8 KB · Views: 374
Last edited:
Ok i know im posting alot here but figured out i can implement a internal signal to use instead of the actual pin. This way i can leave it as OUT and not INOUT and also not have to process it:

Good job! ( had you coded in verilog, it would have worked fine as an output )


Im sure i can also use BIT instead of STD_LOGIC but heh its ok i assume

You can, but "bit" is generally used in non-synthisized code. For synthesis, stick with STD_LOGIC.
 
Last edited:
Hey BrownOut can you check this out... I would simulate but tired heh.. i just tried to guess how this would work. Messing around and trying to make a 32bit shift register.

Pins:
sin : Serial In
lat : Latch Pin
clk : Clock Pin
rst : Reset (clears pins and counter)

Code:
entity shift32 is
    Port ( sin : in  STD_LOGIC;
           lat : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           db : out  STD_LOGIC_VECTOR (31 downto 0));
end shift32;

architecture Behavioral of shift32 is

	signal tempReg : STD_LOGIC_VECTOR (31 downto 0);
	shared variable cnt : integer;	
	
begin

process (clk,lat,rst,sin,tempReg)

begin

	if(rst = '1') then
	  for i in 0 to 31 loop
			tempReg(i) <= '0';
     end loop;
	  
	  cnt := 0;
	elsif(rising_edge(clk)) then
	
		if(sin='1') then
			tempReg(cnt) <= '1';
		else
			tempReg(cnt) <= '0';
		end if;  
		
		cnt := cnt + 1;
		
		if(cnt = 32) then
			cnt := 0;
		end if;

		if(lat = '1') then
			db <= tempReg;
		end if;		
		
	end if; 
	
end process;

end Behavioral;
 
Let me explain what how it should work.. There are 4 signals in and 32 out. There is no serial out , not needed.

LAT = send the data in the register the DB pins.
CLK = clocks the data into the register.
SER = serial data in
RST = Clears the register but wont clear the output unless the LAT is enabled

Internal signals:
TempReg = 32bit shift register data
cnt = current bit we are on, can be 0 to 31

So you clock data in on the rising edge of the ser pin and when cnt reaches 32 its cleared to 0 to start over. You can enable the LAT and see the values for each clock or enable lat when 32 bits are clocked in and change the whole output in 1 shot.

Not sure how good this code is since i made it but seems like it would work
 
A couple things:

The process is a clocked process, so the only signals in the sensitivity list should be clock and reset.
You don't have to use if/else to assign the sin values to the shift register. Just use "tempReg(cnt) <= sin;
You dont need a loop to initialize the tempReg. You can just do this: "tempReg <= (others => '0');
If you make cnt a 5 bit STD_LOGIC_VECTOR, it will roll over by itself.

Otherwise, good job!
 
Thanks wow....

tempReg(cnt) <= sin; -- This makes perfect sense, im not sure why i didnt do it...
tempReg <= (others => '0'); -- I saw that somewhere but didnt know how to use it... thanks a ton

If you make cnt a 5 bit STD_LOGIC_VECTOR,it will roll over by itself. -- Awesome idea! But how would i ? Do i make it a signal ? or can i do that with variables... im still waiting on a certain book to arrive to read
 
If you make cnt a 5 bit STD_LOGIC_VECTOR,it will roll over by itself. -- Awesome idea! But how would i ? Do i make it a signal ? or can i do that with variables... im still waiting on a certain book to arrive to read

signal cnt : STD_LOGIC_VECTOR(5 downto 0)

You'll need this in your design file:

--- Library Files ---
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

The last two libraries include packages that allow you to do the addition on STD_LOGIC_VECTORS.
 
Last edited:
SO you meant 6 bits :D

Also :

Code:
ERROR:HDLParsers:821 - "C:/XWD/Shift32/shift32.vhd" Line 58. Wrong index type for tempReg.
--.. on code
tempReg(cnt) <= sin;
 
SO you meant 6 bits :D

Correct

Also :

Code:
ERROR:HDLParsers:821 - "C:/XWD/Shift32/shift32.vhd" Line 58. Wrong index type for tempReg.
--.. on code
tempReg(cnt) <= sin;

OH right, I guess cnt does have to be an integer. For counters other than indices, you can use STD_LOGIC_VECTOR and the libraries. BTW, here is how I do my shift registers:


Code:
   signal shifter    : STD_LOGIC_VECTOR(MAX_LED-1 downto 0);
   ...
         if(clk_cnter(CNT_MAX) = '1' and clk_cntr_d = '0') then
            if(dir = '0') then
             shifter <= '0' & shifter(MAX_LED-1 downto 1);  -- right shift
            else
             shifter <= shifter(MAX_LED-2 downto 0) & '0';  -- left shift
            end if;  
etc...
 
Last edited:
I added some code to my last message while you were replying. Take a look at it.
 
Ah i see cool, Direction was a nice addition. Im lazy so i usually try make one piece of code so changing which way it shifts in doesnt affect me. I plan to test this out with a PIC as soon as i get my board
 
My FPGA board should be here by friday the latest... had some bill issues heh... anyway i think im understanding FPGAs more and more everyday.

BrownOut since you seem to be the most experienced in this field here... i am going to make a small (very small) LED Blink example with the ability to change blink rates... can you simply go over the code and comment on good/bad parts?
 
Well this doesnt synthesize but looks fine to me...
I get a error:
Code:
INTERNAL_ERROR:Xst:cmain.c:3464:1.56 -  Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-----------------------------------------------------

entity BlinkRate is
port(	myButton:	in std_logic;
	   myClock:		in std_logic;
	   myReset:		in std_logic;
	   myLED:		out std_logic
);
end BlinkRate;

-----------------------------------------------------

architecture myFSM of BlinkRate is
    -- states of myFSM
	 signal myLEDState : STD_LOGIC;
    type state_type is (S0, S1, S2, S3);
    signal next_state, current_state: state_type;
	 shared variable myRate: integer;
	 shared variable myCount: integer;	 -- shared variable cnt : integer;

begin
    
    -- cocurrent process#1: state registers
    state_reg: process(myClock, myReset)
    begin

	if (myReset='1') then
				myLEDState <= '0';
				myRate := 32000000;
				myCount := 0;
            current_state <= S0;
	elsif (myClock'event and myClock='1') then
	    current_state <= next_state;
		 if(myCount=myRate) then
			myLEDState <= not myLEDState;
			myCount := 0;
		else
			myCount :=myCount + 1;
		end if; 
	end if;
	myLED <= myLEDState;
   end process;						  

    -- cocurrent process#2: combinational logic
    comb_logic: process(current_state, myButton)
    begin

	case current_state is

	    when S0 =>
			if myButton='0' then
			    next_state <= S0;
			else
				 myRate := 16000000;
			    next_state <= S1;
			end if;

	    when S1 =>	
			if myButton='0' then 
			    next_state <= S1;
			else
				 myRate := 8000000;
			    next_state <= S2;
			end if;

	    when S2 =>	
			if myButton='0' then
			    next_state <= S2;
			else
				 myRate := 4000000;
			    next_state <= S3;
			end if;

	    when S3 =>
			if myButton='0' then 
			    next_state <= S3;
			else
				 myRate := 32000000;
			    next_state <= S0;
			end if;

	    when others =>
		   myRate := 32000000;
			next_state <= S0;

	end case;

   end process;

end myFSM;

What should happen here is when it first start the initial rate is 32000000 which is the 32mhz on board so its like a 1 second blink. Then when you press the button it cuts the time in half.. 500ms blink then when you press it cuts in 1/2 again 250ms then when you press it cuts in half again... 125ms... now if you press 1 more time it goes back to 1 seconds blink...

Well thats the theory... as you can see it doesnt (COMPILE)(SYNTHESIZE) i like compile word better
 
Last edited:
You have the signal "my_rate" assigned in two different processes. You don't need to reset it to zero in the clock/reset process, because you reset "current_state" to s0, where you can then assign "my_rate" to the initial value. However, in the process "comb_logic" you have states/inputs where "my_rate" is not assigned. YOu should either create a signal called "next_my_rate" and assign "my_rate" in the clock process, or else just make sure that "my_rate" is assigned under every condition in comb_logic. Also, be careful assigning huge numbers to integers. If your software defines integers as 16-bit, it won't hold your 32M number. Instead, figure out how many bits it takes to hold such a number, and use a vector to assign it. ie.

2^n=32MEG => n=log(2)32MEG/n therefore, n=25. Conversly, you can just create a 25-bit counter and pick off sucessively lower bits ( starting w/MSB ) for your blink rate, ie,

Code:
signal counter : STD_LOGIC_VECTOR(24 downto 0)

....


case current_state
...

when s0 -> LED_STATE <= counter(24)

...

when s1 -> LED_STATE <= counter(23)

etc.
Looks like you're on the right track. I like the way you're using the pushbutton to change the blink rate.
 
Last edited:
Thanks a ton, im still a bit confused tho... sorry... just noticed your update... thanks.. the thing is im using the RATE in the clock so it counts to the rate. If i send the counter to LED State nothing will happen really

signal counter : STD_LOGIC_VECTOR[24 downto 0]

how would i set the entire signal value ?

do i simply... counter <= 30842; or something

i think im tired and will tackle this tomorrow.. if i said something stupid here omit that :D im just very sleepy :(
 
how would i set the entire signal value ?

do i simply... counter <= 30842; or something

You don't. Look at my example, I only send a single bit of the counter:

Code:
when s0 -> LED_STATE <= counter(24)

The parenthesis around the "24" means assign bit 24 of the counter.

i think im tired and will tackle this tomorrow.. if i said something stupid here omit that :D im just very sleepy :(

Good idea, heh!
 
There is yet another way, you can do this:

LED_STATE <= counter = "XYZ". Although this abstracts the resultant logic, I don't often use this style.
 
i have to admit. Im still lost but that just means i need to read up more :D Ill figure it out... oh yeah i was thinking of this also.. since i changed myRate to a STD_LOGIC_VECTOR(24 downto 0) can i set it like:
Code:
myRate <= "1111010000100100000000000";

? is that a safe thing?
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top