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;



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

Attachments

  • sim.jpg
    23.8 KB · Views: 376
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

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

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:
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 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 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 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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…