Jump to content
  • 0

Designated Numbers Moore FSM with 4 bit counter


jygcm

Question

Greetings.

I just started out VHDL not long ago,and not quite familiar with Moore FSM.

So I was trying to write this Moore FSM code as shown in Picture of my initial sketch(Link to imgur,safe to click).

 

Quote

*Sketch correct,Both Decoder and MUX should be 1X2,If it's not possible then nothing change.*

Sketch Design Description:

First a CLK(50 MHZ) into a Frequency divider divide it down to (1 HZ)
And then output (1 HZ) to drive the Designated Number "870107" Moore Machine
For the 4 bit counter,When Moore Machine finished counting "870107" the 4 bit counter count 1, like Moore : 8>7>0>1>0>7 
                                                                                                                                                                                   4 bit    : 0>0>0>0>0>1
                                                                                                                                                                                                 1>1>1>1>1>2

                                                                                                                                                                                                 2>2>2>2>2>3
                                                                                                                                                                                                        ... etc  
As for the decoder is for scanning 2 seven segment display then output as Selectors for MUX decide which one count first
Then finally display it on Seven Segment Display.

 

after search for some reference about Moore in VHDL,I'm still stuck.
I'm hoping someone can help me fill-in the missing pieces of my code and to fit into the sketch.

Sincerely Appreciate.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

entity M6B is
    Port ( clk : in  STD_LOGIC;
			  x	: in  STD_LOGIC;
           rst : in  STD_LOGIC;
			  --z	: out STD_LOGIC_VECTOR (6 downto 0);
           AN : out  STD_LOGIC_VECTOR (1 downto 0);
           ledout : out  STD_LOGIC_VECTOR (6 downto 0));
end M6B;

architecture Behavioral of M6B is
type state_type is (s0,s1,s2,s3,s4,s5);
signal state : state_type;
signal ledbcd : std_logic_vector (3 downto 0);
signal ledonc : std_logic_vector (1 downto 0);
signal osc : STD_LOGIC_VECTOR (24 downto 0);
signal refresh_counter: STD_LOGIC_VECTOR (16 downto 0);
signal oscen : std_logic; 
signal dispn :	std_logic_vector (6 downto 0);

begin

process (clk,rst)
begin
	if rst = '1' then
		state <= s0;
	elsif (rising_edge(clk)) then
		case state is
			when s0 =>
				if x = '0' then
					state <= s1;
				else 
					state <= s0;
				end if;
			when s1 =>
				if x = '0' then
					state <= s2;
				else
					state <= s1;
				end if;
			when s2 =>
				if x = '0' then
					state <= s3;
				else
					state <= s2;
			   end if;
			when s3 =>
				if x = '0' then
					state <= s4;
				else
					state <= s3;
				end if;
			when s4 =>
				if x = '0' then
					state <= s5;
				else
					state <= s4;
				end if;
			when s5 =>
				if x = '0' then
					state <= s0;
				else
					state <= s4;
				end if;
	end case;
	end if;
end process;

process (state)
begin
	case state is
		when s0 =>
			AN <= "10";
			ledout <= "0000000";
		when s1 =>
			AN <= "10";
			ledout <= "0000111";
		when s2 =>
			AN <= "10";
			ledout <= "0000000";
		when s3 =>
			AN <= "10";
			ledout <= "1001111";
		when s4 =>
			AN <= "10";
			ledout <= "0000000";
		when s5 =>
			AN <= "10";
			ledout <= "0000111";
	end case;
end process;


end Behavioral;

 

IMG_20180528_052513.jpg

Link to comment
Share on other sites

15 answers to this question

Recommended Posts

@jygcm,

One of the common beginner mistakes is to create a clock using the logic of the board instead.  Since the PLL's won't support a 1Hz clock, this is the only way to make a 1Hz clock.  It's also severely flawed.  Don't do it.  In this case, you have to switch from your 1Hz clock counter to a much faster clock to get your seven segment display working.  This will create a "clock domain crossing" (CDC) that you may find difficult to deal with properly.  The problem with unmitigated CDC's is that the logic on the other side might not act properly.   Worse, it will often act properly in simulation, but then fail in hardware.  This will leave you scratching your head and wondering what went wrong.

My recommendation for beginners is that they only ever use the system clock.  To do this, you'll often want to create a clock enable signal that will be true for one clock per second--such enable signals are only ever one clock wide or this won't work.  Inside your clocked logic, you should then have something like:

process(clk)
begin
  if (rising_edge(clk)) then
    if (i_ce) then ----- this is the enable signal
      ---
      --- Your logic would go here
      ---
    end if;
  end if;
end process;

I discuss generating such enable signals in this post from some time ago.

Dan

P.S.  I only just learned VHDL in the last two weeks or so, after having used Verilog for years.

Link to comment
Share on other sites

not sure what you are trying to do.  You have 1Hz going into designated number which connects to 4 bit counter with a comment of "moore machine one cycle".  The frequency divider has three outputs of which two go a decoder and a mux for reasons.  The states also have names s0 to s5.  The FSM seems to be "ignore input until a zero is seen, otherwise advance state".  I don't see a relation to the diagram.

I don't understand either the block diagram or the problem description or the proposed code.  You need to specify the problem in a more understandable format or post this to a forum that has better mindreaders.

Link to comment
Share on other sites

1 hour ago, Piasa said:

not sure what you are trying to do.  You have 1Hz going into designated number which connects to 4 bit counter with a comment of "moore machine one cycle".  The frequency divider has three outputs of which two go a decoder and a mux for reasons.  The states also have names s0 to s5.  The FSM seems to be "ignore input until a zero is seen, otherwise advance state".  I don't see a relation to the diagram.

I don't understand either the block diagram or the problem description or the proposed code.  You need to specify the problem in a more understandable format or post this to a forum that has better mindreaders.

First of all,Thank you for reply.
And apology for the confusing sketch.


Let me try to describe the initial design this way;
First a CLK(50 MHZ) into a Frequency divider divide it down to (1 HZ)
And then output (1 HZ) to drive the Designated Number "870107" Moore Machine
For the 4 bit counter,When Moore Machine finished counting "870107" the 4 bit counter count 1, like Moore : 8>7>0>1>0>7 
                                                                                                                                                                                   4 bit    : 0>0>0>0>0>1
                                                                                                                                                                                                 1>1>1>1>1>2

                                                                                                                                                                                                 2>2>2>2>2>3
                                                                                                                                                                                                        ... etc  
As for the decoder is for scanning 2 seven segment display then output as Selector for MUX decide which one count first *The Decoder and MUX should be 1X2,I mis-drew it.If it's not possible using it then nothing change.*
Then finally display it on Seven Segment Display.


I hope this way of describe is clearly enough for you to help me out.

Link to comment
Share on other sites

1 hour ago, D@n said:

@jygcm,

One of the common beginner mistakes is to create a clock using the logic of the board instead.  Since the PLL's won't support a 1Hz clock, this is the only way to make a 1Hz clock.  It's also severely flawed.  Don't do it.  In this case, you have to switch from your 1Hz clock counter to a much faster clock to get your seven segment display working.  This will create a "clock domain crossing" (CDC) that you may find difficult to deal with properly.  The problem with unmitigated CDC's is that the logic on the other side might not act properly.   Worse, it will often act properly in simulation, but then fail in hardware.  This will leave you scratching your head and wondering what went wrong.

My recommendation for beginners is that they only ever use the system clock.  To do this, you'll often want to create a clock enable signal that will be true for one clock per second--such enable signals are only ever one clock wide or this won't work.  Inside your clocked logic, you should then have something like:


process(clk)
begin
  if (rising_edge(clk)) then
    if (i_ce) then ----- this is the enable signal
      ---
      --- Your logic would go here
      ---
    end if;
  end if;
end process;

I discuss generating such enable signals in this post from some time ago.

Dan

P.S.  I only just learned VHDL in the last two weeks or so, after having used Verilog for years.

@D@n:

Thank you for your explicit explaining.
I've read your recommended posts,that some information that need time to process.
I noted that the code example in those posts are Verilog not sure what it has to do with VHDL...can Verilog's coding method be use on VHDL?
I've considered using enable signal as well,I've set one under architecture named oscon (one_second_count_enable) just not sure how to apply it though.

 

If I use this,can I apply CASE inside ? 
which logic in my design fit into this format?
Moore ? 4 bit Counter? MUX ? decoder?
And do I need to write a CASE solely for Seven Segmet Display output? in this format as well?

process(clk)
begin
  if (rising_edge(clk)) then
    if (i_ce) then ----- this is the enable signal
      ---
      --- Your logic would go here
      ---
    end if;
  end if;
end process;


 

Link to comment
Share on other sites

@jygcm,

You can put a case statement within an if statement, yes.

Which logic should use the above format?  Anything that depends upon a clock, but which you want to change at a rate slower than your clock rate.  Since you have chosen a two process state machine implementation, only the clocked process of the two processes needs to fit this format.

The seven segment output is where you are going to have some trouble.  To be successful with that, you need to rotate through which segment you send current to.  Digilent recommends a rotation scheme of about 1ms.  Hence, for that to work, you'd need another ce-type signal to control the logic within that portion of your design.  So (sadly) that process is likely going to need to be rewritten.  While it might work as is, I'm betting that the 7-segment display has more digits than just the one.

Dan

Link to comment
Share on other sites

OK the problem is clear from the whiteboard, but I don't solve homework problems (sorry).

 "Moore" refers to one type of state machine (as opposed to "Mealy") where the outputs do not depend on the inputs during the same clock cycle.
In other words, if I change the switches, the display output changes only at the following clock cycle, not immediately.

The counters are supposed to look like this:

c1:  8 7 0 1 7 8 7 0 1 7 8 7 0 1 7 8 7 0 1 7 etc
c2:  0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3

Find a "state machine" or "FSM" example. The "Moore" / "Mealy" thing is probably more common among academics than normal engineers - Moore is the default, and if you try Mealy without a strong grasp on the implications I guarantee your ship will sink. fast. once the design goes past trivial size.

Link to comment
Share on other sites

@D@n 
Yes,I've seen the article before,but I don't get the part that how to make it work for two counters,one that counts specifics numbers and one counts naturally after first counter and only using 2 digits S-S-D.

@xc6lx45

This isn't quite a homework.I recently participated in a sort of hardware design tutoring class,and well,they'll come up a project once a while,and this is the one I couldn't solve.

Well,still thanks for the extra fill-in on my subject.
I don't expect others to finish it for me and just let me take it and go,what I do need is some clues and examples to help out.

Link to comment
Share on other sites

@jygcm,

The trick is to separate the problem.  You should have at least three parts:

  1. The first part is a module that does nothing but display the value given to it.  Since there are 7-segments in each 7-segment display, this piece should take 7-bit inputs (8 w/ the decimal point) and display exactly the selected LEDs and no more.  There's no requirement at this first part to make them valid digits--they just need to be the arbitrary configurations you require.
  2. The next step is to convert a 4-bit hexadecimal number to its associated 7-bit representation, which will then feed the part you just got working above.
  3. The third step is to implement the counters you are talking about.  And, oh by the way, by the time you have #1 working above, you'll know how to do this part.

Let me ask another question, though: how are you planning on simulating this and testing that your code works?  Without proper preparation before going to the FPGA, you'll quickly find yourself with a design that doesn't work and no idea why not.  I call this FPGA Hell.  You should at least start thinking about this problem now.

Dan

Link to comment
Share on other sites

Hi,

one comment: your VHDL code (before D@n's proposed pattern) isn't strictly a "Moore" machine because of the asynchronous reset: It's outside the "raising edge" clause: reset changes => the outputs change immediately during the same clock cycle => Mealy.

if rst = '1' then
		state <= s0;
	elsif (rising_edge(clk)) then

But that's nitpicking, it should work even though it raises red flags as a design practice.
I can't tell you exactly why it doesn't work. Try to run a simulation, it's surprisingly simple. Personally, I'm a big fan of the open-source iverilog simulator to study my own RTL outside the FPGA environment, but that won't help with VHDL.

If it gives some motivation, running into dead-ends and exploring them is (IMHO) the best way to learn if you have the time and motivation.

-----------

Now this part may even create more confusion, but it might be useful for a "clean" demo running at 1 Hz:
According to this post, I can use D@n's proposed "clock enable" signal but to gate the clock itself with a BUFGCE primitive. This outputs a "true" clock signal in a sense that it connects to dedicated clocking resources on the FPGA fabric. It's something the instructor should provide and it would be a fairly unusual approach for a real-world design, but it allows a 1:1 implementation as drawn in the sketch.

 

Link to comment
Share on other sites

How should the FSM should handle 8 7 0 1 1 8 8 8 7 0 1 7 8 7 0 0 0 1 7?

87011 is not 87017.

8887017 contains 87017.  But if 8701 was seen before, the 87017 seen occurs after 8887.

8700017 conatins 870 and 17, but has two extra 0's.

I don't think any FSM model allows async inputs that modify state.

I've always found that Mealy is the FSM that devs want to write -- even when they write Moore/Mendevev FSMs.  Mealy provides next-state/next-value logic -- often avoiding code duplication.  But it uses more lines of code so it is rarely used.

For this context, VHDL and Verilog are basically the same.  This problem doesn't make use of any Verilog/VHDL specific features and both languages handle the general logic design in very similar ways.

In terms of using the CE on DFFs vs the CE on BUFGCE, just make sure you constrain the CE signal to the BUFGCE.  The CE signal does have a setup/hold similar to a FF and shouldn't be changing close to a clock edge that affects logic.  Because designs can have thousands of different CE signals for DFF control sets, but normally only 32 BUFGCE's, the CE feature of the BUFGCE is less used.

Link to comment
Share on other sites

8 hours ago, xc6lx45 said:

... so they can complain more efficiently about Vivado slowness :rolleyes:

I guess my statement isn't accurate.  Mealy/Moore/Mendevev could all be written with two processes.  I guess my real statement is that the single clocked process FSM is not what people want to write, logically.  But the languages make this style common.

Link to comment
Share on other sites

well what I meant is simply this, having a combinational input-output path in a block creates a top-level optimization problem that the tools aren't particularly good at. They mainly optimize blocks individually, and then this design style creates a register-less path from one end of the design to the other and back... For example, the AXI specs explicitly require one register minimum for a reason.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...