- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all, I am new here. I tell you my problem. I have been now several days trying to figure it out how to control shift registers SIPO 74LS164 with my FPGA. I am doing a clock, displaying hours, minutes and seconds with NIXIE tubes. What I need to do is to send each second, 24 bits, and remain those 24 bits displaying in the NIXIE tubes during the second, till the new second comes and new 24 bits are sent. Maybe this is a stupid question but I don't know how to produce my clock signal and my serial output to control this ICs.I already have a vector of 24 bits and the schematic of how cascading these ICs so that's not the problem. I think you get which my problem is.Please if somebody can help me would be so so great!Thank you very muchRegards
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Design a finite state machine. The states may be:
s0 - wait for a internal "start" signal goes to '1', that triggers the transmission. If this is true, load register n with 24 ( 24 bits ) and go to state s1. s1- put a data bit on 74LS164 serial in. go to state s2 s2 - rise 74ls164 clock signal. go to state s3 s3 - place '0' on 74ls164 signal. go to state s4 s4 - shift data register, decrement n register. go to state s5. s5 - if n register is 0 you ended your transmission. If no 0, go to state s1. Translate this to vhdl. You could do with fewer states.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much for your reply, it helped me a lot on how focus the problem. Now my problem is with the state machine itself. I paste here the code
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; entity control_unit2 IS port (clk2: in std_logic; clk: in std_logic; data : in std_logic_vector (23 downto 0); data_out : out std_logic; clk_out : out std_logic); end control_unit2; Architecture Behavioral of control_unit2 is type state_type is (start, load, pulse, rst, shift, check); signal pstate, nstate : state_type := start; signal data_reg : std_logic_vector (23 downto 0); signal data_aux: std_logic ; signal clk_aux: std_logic; signal trigger: std_logic := '0'; BEGIN clocked: PROCESS (clk2,clk) BEGIN if clk2'event and clk2 = '1' then pstate <= nstate; END IF; END PROCESS clocked; states: process(pstate,data,trigger, clk) variable i : integer; begin case pstate is when start => i := 24; data_reg <= data; nstate <= load; when load => data_aux <= data_reg(i); nstate <= pulse; when pulse => clk_aux <= '1'; nstate <= rst; when rst => clk_aux <= '0'; nstate <= shift; when shift => i := i - 1; nstate <= check; when check => if i = 0 then nstate <= waiting; else nstate <= load; end if; end case; end process states; clk_out <= clk_aux; data_out <= data_aux; END Behavioral; The problem is in the state 0. My start signal, following your explanation, is a falling edge of the clock clk. That falling edge tell me when a second starts, i.e. when I must start sending data through the output. When I try to synthesize this I get this error: Error (10822): HDL error at control_unit2.vhd(55): couldn't implement registers for assignments on this clock edge I don't know where is the problem and what should I do to solve it. Can you help me? Thank you again. Regards- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code looks very good. But u have to fix some things:
a-u have 2 inputs clocks: clk and clk2. Your design needs no more than 1 clock. b-u separate the register description from the next state logic. I like that, it's very clear. But when u declare pstate and nstate u assign an initial state ( start ). This doesn't work. It only have sense for simulation purposes. Set an initial state in the register description: if( reset = '0' ) then pstate <= start; elsif(clk'event and clk = '1') then pstate <= nstate; end if; c-You have a trigger signal. How do u use it? And where you generate it? d-I don't now where is the line 55, that generates the error. Regards.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your reply.
Regarding the 2 clocks, one its acting like a clock itself (clk2), but the other one is the 1 Hz signal generated to get the seconds value and synchronized with the DCF77 signal (it's a long wave time signal, which I use for this project). This 1 Hz signal is generated in another block (I'm doing this with blocks in Quartus II). I need that 1 Hz clock to send the datas at the beginning of the second (falling edge of this signal). b. I think I get the point but the problem is that I need, like I said before, to go to the "start" state, each time I get a falling edge on clk (1 Hz signal) and that's the problem I have, I don't know how to do this. c. Sorry for that, it's just something I was trying and then forgot to delete it. d. I pasted you another code sorry, just change in the description of the "start" state and here it is and it's where I get the error: begin case pstate is when start => if clk'event and clk = '0' then -- Falling edge on the 1 Hz clock i := 24; data_reg <= data; nstate <= load; else nstate <= start; end if; What I am trying to do here, is to create a "bucle" in the "start" state, waiting for that falling edge. I hope I make myself clear. Thank you again, very much. Regards- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok. The second clock ( clk ) is like a trigger signal. I write the transitions this way:
process... begin nstate <= pstate; clk2_next <= clk2_reg; dat_next <= dat_reg; n_next <= n_reg; case pstate is when reposo => if ( clk = '0' ) then --- falling edge nstate <= etapa1; end if; when etapa1 => dat_next <= shift_reg(23); nstate <= etapa2; when etapa2 => shift_next <= shift_reg(22 downto 1) & '0'; n_next <= n_reg - 1; when etap3 => ... -- up clkout when etapa4 => -- down clkcout when etapa5 => if( n_reg = 0 ) then nstate <= reposo; else nstate <= etapa1; when others =>.... I worked the clock and data out as register.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you again for your time.
I don't know if I got it. If I understood, this is what you said: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; entity control_unit2 IS port (clk2: in std_logic; clk: in std_logic; reset : in std_logic; data : in std_logic_vector (23 downto 0); data_out : out std_logic; clk_out : out std_logic); end control_unit2; Architecture Behavioral of control_unit2 is type state_type is (reposo, etapa1, etapa2, etapa3, etapa4, etapa5); signal pstate, nstate : state_type; signal data_reg : std_logic_vector (23 downto 0); signal data_aux: std_logic; signal clk_aux: std_logic; signal clk_next: std_logic; BEGIN clocked: PROCESS (clk2) BEGIN if reset = '1' then pstate <= reposo; elsif clk2'event and clk2 = '1' then pstate <= nstate; END IF; END PROCESS clocked; states: process(pstate,data,clk) variable i : integer; begin clk_next <= clk; data_reg <= data; case pstate is when reposo =>
if clk_next = '0' then
nstate <= etapa1;
i := 24;
end if;
when etapa1 => data_aux <= data_reg(23); nstate <= etapa2; when etapa2 => data_reg <= data_reg(22 downto 0) & '0'; i := i - 1; nstate <= etapa3; when etapa3 => clk_aux <= '1'; nstate <= etapa4; when etapa4 => clk_aux <= '0'; nstate <= etapa5; when etapa5 => if (i = 0) then nstate <= reposo; else nstate <= etapa1; end if; end case; end process states; clk_out <= clk_aux; data_out <= data_aux; END Behavioral; I put in black, the critical point of the problem. How can that be a falling edge?. If i write here: when reposo =>
if clk'next'event and clk_next = '0' then -- or with clk itself
nstate <= etapa1;
i := 24;
end if;
I will get an error like this: "Error (10822): couldn't implement registers for assignments on this clock edge" And with the code like it is wrote above, I get in the clock output a clock signal working during half second (time when clk = 0) and nothing in the data output. I really don't know where is the mistake. I also looked the input data for this block and I get them right but not in the ouput. On the other hand, in clk_out I should just have 24 pulses instead of the whole half second with the clk2 frequency. Any tips? Thank you very much again and sorry if my questions are very basic... I'm pretty new with VHDL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Probably you have an inferred latch on dat_reg. Use next state logic like you do with the state reg:
if reset = '1' then pstate <= reposo; data_reg <= ( others => '0' ); clk_reg <= '0'; dat_reg <= '0'; i_reg <= ( others => '0' ); elsif clk2'event and clk2 = '1' then pstate <= nstate; data_reg <= data_next; -- next state logic for the registers clk_reg <= clk_aux; dat_reg <= dat_aux; i_reg <= i_next; END IF; states: process(pstate,data,clk) begin clk_next <= clk; data_aux <= data_reg; case pstate is when reposo => if clk_next = '0' then nstate <= etapa1; i_reg <= to_unsigned(24, 5); -- declare i_reg as a 5 bits unsigned vector end if; when etapa1 => data_aux <= data_reg(23); nstate <= etapa2; when etapa2 => data_aux<= data_reg(22 downto 0) & '0'; -- don't use reg, use next ( or aux as u call it ) i_next := i_reg - 1; -- i don't like variables. I generate a register above nstate <= etapa3; when etapa3 => clk_aux <= '1'; nstate <= etapa4; when etapa4 => clk_aux <= '0'; nstate <= etapa5; when etapa5 => if (i = 0) then nstate <= reposo; else nstate <= etapa1; end if; end case; end process states; clk_out <= clk_reg; data_out <= dat_reg; END Behavioral; Something like this.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi again, thank you for your answer.
Still getting at the output clk_out, a clock signal always running, instead of the 24 pulses I should (or want to) have, and nothing in the data output. I am handling now the "trigger" signal, in a separate block, detecting there the falling edge and sending a pulse to the State Machine block when it is detected. When I compile the following code, I don't get errors but I get a lot of warnings. One of them are: Inferring latches for signals : i_next, data_next, clk_aux and data_aux. And: Latch data_next(23) has unsafe behavior (this happens with all data_next bits). I paste here the code and please tell me where is the error, I was a bit confused with the last answer with so many _reg, _aux and _next and I don't know if I understood it.
entity control_unit2 IS
port (clk2: in std_logic;
trigger: in std_logic;
data : in std_logic_vector (23 downto 0);
data_out : out std_logic;
clk_out : out std_logic);
end control_unit2;
Architecture Behavioral of control_unit2 is
type state_type is (start, load, pulse, rst, shift, check, hold);
signal pstate, nstate : state_type;
signal data_reg : std_logic_vector (23 downto 0);
signal data_next: std_logic_vector (23 downto 0);
signal i_reg : unsigned (4 downto 0);
signal i_next: unsigned (4 downto 0);
signal data_aux: std_logic ;
signal clk_aux: std_logic;
BEGIN
clocked: PROCESS (clk2)
BEGIN
if clk2'event and clk2 = '1' then
if trigger = '1' then
pstate <= start;
else
pstate <= nstate;
i_reg <= i_next;
data_reg <= data_next;
end if;
END IF;
END PROCESS clocked;
states: process(pstate,data,trigger)
begin
case pstate is
when start =>
i_next <= to_unsigned(24,5);
data_next <= data;
nstate <= load;
clk_aux <= '0';
when load =>
data_aux <= data_reg(23);
nstate <= pulse;
clk_aux <= '0';
i_next <= i_reg;
when pulse =>
data_next <= data_reg(22 downto 0) & '0';
clk_aux <= '1';
nstate <= rst;
i_next <= i_reg;
when rst =>
i_next <= i_reg;
clk_aux <= '0';
nstate <= shift;
when shift =>
i_next <= i_reg - 1;
nstate <= check;
when check =>
if i_reg = 0 then
nstate <= hold;
else
nstate <= load;
end if;
when hold =>
nstate <= hold;
end case;
end process states;
clk_out <= clk_aux;
data_out <= data_aux;
END Behavioral;
Thank you again Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First of all, i recommend you when you design a finite state machine in vhdl use next state logic approach for all regiters. VHDL is not a programming language like C or basic. Read the books of Stephen Brown or Pong Chu to understand the method.
Some signals has no a default value. This is the cause of the error: states: process(pstate,data,trigger) begin i_next <= i_reg; -- default value data_next <= reg; -- default value .... -- and this for all registers case pstate is when start => i_next <= to_unsigned(24,5); data_next <= data; nstate <... The other things is the name and purpose of signals are bit confused. I give a suggestion: entity control_unit2 IS port( reset : in std_logic; clk : in std_logic; trigger: in std_logic; data : in std_logic_vector (23 downto 0); data_out : out std_logic; clk_out : out std_logic ); end control_unit2; Architecture Behavioral of control_unit2 is type state_type is (start, load, pulse, rst, shift, check, hold); signal pstate, nstate : state_type; signal data_reg, data_next : std_logic_vector (23 downto 0); signal i_reg, i_next : unsigned (4 downto 0); signal datout_reg, datout_next: std_logic ; signal clkout_reg, clkout_next: std_logic; BEGIN clocked: PROCESS (clk) BEGIN if( reset = '1' ) then pstate <= start; i_reg <= ( others => '0' ); data_reg <= ( others => '0' ); datout_reg <= '0'; clkout_reg <= '0'; elsif clk'event and clk = '1' then pstate <= nstate; i_reg <= i_next; data_reg <= data_next; datout_reg <= datout_next; clkout_reg <= clkout_next; END IF; END PROCESS clocked; states: process(pstate,data,trigger) -- complete de sensitivity list begin data_next <= data_reg; i_next <= i_reg; clkout_next <= clkout_reg; datout_reg <= datout_next; case pstate is when start => i_next <= to_unsigned(24,5); data_next <= data; nstate <= load; clk_next <= '0'; when load => datout_next <= data_reg(23); nstate <= pulse; clk_next <= '0'; i_next <= i_reg; when pulse => data_next <= data_reg(22 downto 0) & '0'; clkout_next <= '1'; nstate <= rst; i_next <= i_reg; when rst => i_next <= i_reg; clkout_next <= '0'; nstate <= shift; when shift => i_next <= i_reg - 1; nstate <= check; when check => if i_reg = 0 then nstate <= hold; else nstate <= load; end if; when hold => nstate <= hold; -- GENERATE a 1 CLOCK PULSE SIGNAL IN '1' TO TELL OTHER CIRCUIT THAT -- YOU FINISH THE TRANSMISSION. THEN RETURN TO START STATE TO -- WAIT ANOTHER TRIGGER end case; end process states; clk_out <= clkout_reg; data_out <= datout_reg; END Behavioral; I hope this fix the errors.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Finally! It worked! I didn't use the "hold" state at the end, I didn't see it neccesary and it seems to work fine, I'll continue checking it to see if its consistent in time. However I paste here the code again, in case someone has the same problem or see something wrong in it.
I don't know how to thank you for your help, you saved me. I wish one day I can return the favor. Thank you very much!LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
entity control_unit2 IS
port (reset: in std_logic;
clk: in std_logic;
trigger: in std_logic;
data : in std_logic_vector (23 downto 0);
data_out : out std_logic;
clk_out : out std_logic);
end control_unit2;
Architecture Behavioral of control_unit2 is
type state_type is (start, load, pulse, rst, shift, check);
signal pstate, nstate : state_type;
signal data_reg : std_logic_vector (23 downto 0);
signal data_next: std_logic_vector (23 downto 0);
signal i_reg : unsigned (4 downto 0);
signal i_next: unsigned (4 downto 0);
signal datout_reg, datout_next: std_logic ;
signal clkout_reg, clkout_next: std_logic;
BEGIN
clocked: PROCESS (clk,reset)
BEGIN
if (reset = '1') then
pstate <= start;
i_reg <= (others => '0');
data_reg <= (others => '0');
datout_reg <= '0';
clkout_reg <= '0';
elsif clk'event and clk = '1' then
pstate <= nstate;
i_reg <= i_next;
data_reg <= data_next;
datout_reg <= datout_next;
clkout_reg <= clkout_next;
end if;
end process clocked;
states: process(datout_reg, pstate,data,trigger,data_reg,clkout_reg,i_reg)
begin
data_next <= data_reg;
i_next <= i_reg;
clkout_next <= clkout_reg;
datout_next <= datout_reg;
case pstate is
when start =>
if trigger = '1' then
i_next <= to_unsigned(24,5);
data_next <= data;
nstate <= load;
clkout_next <= '0';
else
nstate <= start;
end if;
when load =>
datout_next <= data_reg(23);
nstate <= pulse;
clkout_next <= '0';
i_next <= i_reg;
when pulse =>
data_next <= data_reg(22 downto 0) & '0';
clkout_next <= '1';
nstate <= rst;
i_next <= i_reg;
when rst =>
i_next <= i_reg;
clkout_next <= '0';
nstate <= shift;
when shift =>
i_next <= i_reg - 1;
nstate <= check;
when check =>
if i_reg = 0 then
nstate <= start;
else
nstate <= load;
end if;
end case;
end process states;
clk_out <= clkout_reg;
data_out <= datout_reg;
END Behavioral;
Pdta: I will read one of those books! Thanks!

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