0

I know the question sounds strange and vague, but I got a problem getting around the Verilog. I got a FSM which has to use a 4 7 segment displays, at one state it should show only one number on one display, at other it should use all 4 displays to display a string. My question is how can I actually get around the always@ blocks with this kind of problem. I've tried setting in one always@ two different cases in a If else block, but it didn't work out. Tried also making two modules one for the number and the other for the string, assigning different output ports but the thing is that it has to point to the same hardware ports, and it fails on the bitstream.

Could someone of you give me some tips?

Ok, I will post some code, but the main picture is that I have a master state machine and then I got another state machine. Depending on the state of the other FSM I output state number on the display. But in a different state of the master state machine I have to display a message on the 4 7segment displays. What I got now is: Here I used CLK in order to make the message

always@(BIN_IN or CLK) begin
if(FAIL==1) begin
     case(state)
           left:
           begin
               HEX_OUT [6:0] <= F;
               SEG_SELECT_OUT <= 4'b0111;
               state <= midleft;
           end
           midleft:
           begin
               HEX_OUT [6:0] <= A;
               SEG_SELECT_OUT <= 4'b1011;
               state <= midright;
           end
//same for the rest
end
else begin  
case (BIN_IN)
4'h0 : begin
    HEX_OUT [6:0] <= 7'b1000000;
    SEG_SELECT_OUT <= 4'b0111;
end
//same logic for the other cases

Board used is Xilinx Basys 3 using vivado synthesising tool

Thanks

3
  • all the four 7-segments share the same data line? If no, a simple if else statement would solve the problem. Commented Nov 12, 2015 at 5:59
  • It would be helpful to either see the code you are using or the board you are synthesizing for as possible solutions vary depending on some factors dependent on these. Commented Nov 12, 2015 at 10:03
  • 2
    Your are inferring combinational logic with always@(BIN_IN or CLK), and RTL behavior will not match synthesized gates. At minimum, you need to change it to always@(posedge CLK) to make it synchronous. Commented Nov 12, 2015 at 16:52

1 Answer 1

1

As Greg said:

always@(BIN_IN or CLK)

Infers combinational logic. An FSM cannot be created with combinational logic alone. As you know, a FSM needs to be able to store the state between each clock.

always@(posedge CLK)

Infers flipflops into your design. That is, the operations you do inside this always loop will be stored until the next positive edge. If you put all of the design inside this always block you will end up with a typical moore-machine where your outputs will only update on every positive clock edge.

It is a bit hard to understand what you are trying to create from your code-snippet. You are talking about two FSM's, but it seems to me that you are trying to do one combinational operation and one clocked operation. If you want your design to update some outputs - like BIN_IN - combinationally(that is, immediately) you have to do these assignments outside of the always@(posedge CLK) block. Use a always@(posedge CLK) block to update your FSM-values and then use a combinational always@(BIN_IN or FAIL) block to infer a multiplexer that will choose between your FSM-output and other outputs. Something like this might work:

always@(posedge CLK)
  begin
    case(state)
    left:
    begin
      FAIL_HEX_OUT <= "A";
      FAIL_SEG_OUT <= 4'b1011;
      state <= midleft;
    end
    //Rest of statements
    endcase
  end

always@(FAIL or BIN_IN or FAIL_SEG_OUT or FAIL_HEX_OUT)
  begin
    if(FAIL == 1) begin
      HEX_OUT <= FAIL_HEX_OUT;
      SEG_SELECT_OUT <= FAIL_SEG_OUT;
    end else begin
      case(BIN_IN)
        //your statements
      endcase
   end
 end

Additionally, this wont work:

HEX_OUT [6:0] = A;

do this to assign ascii to a reg

HEX_OUT [6:0] = "A";

I also assume that you are using endcase to close your case-statements. I have made your code-snippet compile here: http://www.edaplayground.com/x/P_v

Edit: I changed the sensitivity list on the combinational logic. The above code wouldn't have worked earlier.

Because you have posted so little of your code it is hard to figure out what you actual problem is. I assume that you only have one output port for to control all the 7-segment displays. In that case you need to cycle through each SEG_SELECT_OUT and set HEX_OUT for each display when you wish to output FAIL. This, in turn, implies that each display also has the ability to store the HEX_OUT signal that it receives, and your outputs (probably SEG_SELECT_OUT) must enable the write functionality of these display registers. Check that this is the case. I also assume that your real-time-counter that counts 30 seconds sets the FAIL flag when it completes, and is reset every time the maze(I have no idea what you mean when you say maze) is completed. You say that you need to change the number, and I assume that you are talking about outputting the number in BIN_IN on your display and that BIN_IN is changed elsewhere. All of this should work in the code above.

Without more information it is hard to help any further.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. The whole project consists of a top module and 6 sub modules to the top. So everything is nested and it now looks complicated. So I have a master state machine and a maze machine. When I enter lets say state 3 of the master I go to the maze machine and then I have to finish it and pass the finished result to the master. Also I have to count 30 sec in which I have to complete the maze, If I cannot I have to display message.
I don't really know how this might work in the 7segment module as In once case it has to change the numbers and in the other it has to use all the segments to display a message
Have you solved the problem? If not, I strongly reccomend that you provide some more code.
Well, my point here is to get a hint how to make it work, I mean some ways that people usually do when they got the same problem. Anyway, I did manage to correct it. The problem was with the FAIL flag. It was because I used same if-else block to set and reset it. When I change only to set it on one place and reset it in totally independent place it worked well. Thanks anyway!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.