0

I am creating a register file that has 4 empty 4 bit registers, and with each clock cycle, a register gets a value pushed onto it, and then this value is displayed using a 7 segment decoder. If the register is empty, there should not be a display, but once a value is loaded to the register, then there should be a display. I tried writing the verilog code for the 7 segment decoder where there should only be an output if En = 1. My problem is that instead of not displaying anything, the 7 segment decoder will display zero until a value is added to the register, in which case then the decoder will display the loaded value. Here is the verilog code.

module seven_seg_decoder(S, Z, Y, X, W,En);
input Z,Y,X,W,En; 
output [6:0] S;
reg [6:0] S;

always @(En)
    begin
        case({Z,Y,X,W,En})
            5'b00001: S = 'b0000001;
            5'b00011: S = 'b1001111;
            5'b00101: S = 'b0010010;
            5'b00111: S = 'b0000110;
            5'b01001: S = 'b1001100;
            5'b01011: S = 'b0100100;
            5'b01101: S = 'b0100000;
            5'b01111: S = 'b0001111;
            5'b10001: S = 'b0000000;
            5'b10011: S = 'b0000100;
            5'b10101: S = 'b0001000;
            5'b10111: S = 'b1100000;
            5'b11001: S = 'b0110001;
            5'b11011: S = 'b1000010;
            5'b11101: S = 'b0110000;
            5'b11111: S = 'b0111000;

        endcase
    end
endmodule

When the register is loaded with a value, I have an output come from the register saying that it is loaded, and that is used as the input for the enable on this decoder

Zebs
  • 27
  • 1
  • 1
  • 10

1 Answers1

1

Look at the possible encodings of {Z, Y, X, W, En} that you've enumerated:

5'b00001: S = 'b0000001;
5'b00011: S = 'b1001111;
5'b00101: S = 'b0010010;
5'b00111: S = 'b0000110;
5'b01001: S = 'b1001100;
5'b01011: S = 'b0100100;
5'b01101: S = 'b0100000;
5'b01111: S = 'b0001111;
5'b10001: S = 'b0000000;
5'b10011: S = 'b0000100;
5'b10101: S = 'b0001000;
5'b10111: S = 'b1100000;
5'b11001: S = 'b0110001;
5'b11011: S = 'b1000010;
5'b11101: S = 'b0110000;
5'b11111: S = 'b0111000;
//     ^ Look here

All of the values of En are 1! You never told the module what to do if En is 0. It doesn't know to blank out the display. You need to give it something to do in that case.

You have a few options:

Simple Solution
You can add a default clause that blanks the display in all cases that haven't been enumerated:

 default: S = 'b0000000; //change to whatever means "turn everything off"

Needlessly Complex Solution
You could get more precise by using 5'bxxxx0 as a clause and the casex statement:

casex ({Z,Y,X,W,En})
    // all other enumerated cases
    5'bxxxx0: S = 'b0000000; //change to "everything off"
    default:  S = 'b0000000; //change to "everything off"

But know that there are some potential pitfalls to casex that can make it difficult to use correctly and lead to surprising behavior. Also note that this ends up being the same as the first, simple solution. I'd avoid it for now.

(My) Preferred Solution

This is effectively the same as the first two, but I think the intention is much more clear:

always @(*)
    begin
        if (!En)
            S = 'b0000000; // change to "everything off"

        else
            case({Z,Y,X,W,En})
                5'b00001: S = 'b0000001;
                5'b00011: S = 'b1001111;
                5'b00101: S = 'b0010010;
                5'b00111: S = 'b0000110;
                5'b01001: S = 'b1001100;
                5'b01011: S = 'b0100100;
                5'b01101: S = 'b0100000;
                5'b01111: S = 'b0001111;
                5'b10001: S = 'b0000000;
                5'b10011: S = 'b0000100;
                5'b10101: S = 'b0001000;
                5'b10111: S = 'b1100000;
                5'b11001: S = 'b0110001;
                5'b11011: S = 'b1000010;
                5'b11101: S = 'b0110000;
                5'b11111: S = 'b0111000;
                default: S = 'b0000000; // change to some error code
            endcase       
    end

The advantage of this solution is that the goal of your code is much more clear: if En is not true, then the rest of the signals don't matter. We clear the display. This happens with the other solutions as well, but this structure makes it more obvious what is going on.

The default case here technically isn't necessary. There shouldn't be any cases where En is true that aren't enumerated. But that's a lot of digits to type out. If you made a typo, in those cases, having a default that forces an error display (perhaps just the center line of the 7seg display?) will help you identify a bug.

A few other notes:

  1. You should avoid using X and Z as variable names. They may be confused for "don't care" and "high impedance". It makes the code harder to follow than it needs to be.

  2. I've changed your sensitivity list. Greg correctly pointed out that if you want your output to be correctly updated when the inputs W, X, Y and Z change, you need the always block to be triggered when they change. The * operator will tell the Verilog compiler to infer the correct sensitivity list based on the contents of the always block. (Note that this won't look into the tasks or functions to decide the sensitivity list.)

  3. I strongly suggest you put all of your bit patterns in parameters to make your code more readable.

Community
  • 1
  • 1
skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
  • I see what you are saying, but if I do put in the clause that you mentioned, wouldn't that still display an 8? The default cause creates the same output as the case 5'b10001 – Zebs Dec 08 '16 at 23:11
  • Sorry I accidentally hit enter too soon. I edited the comment – Zebs Dec 08 '16 at 23:13
  • I have no idea what your output encoding is. Change it to whatever means "display nothing" – skrrgwasme Dec 08 '16 at 23:13
  • Sorry, I have been looking at this for so long I just assumed other people would know everything about it. Thank you so much – Zebs Dec 08 '16 at 23:15
  • @Zebs Actually, hold on a few minutes.. Let me edit that. I have some better ideas for you. – skrrgwasme Dec 08 '16 at 23:15
  • 1
    `Z`, `Y`, `X`, and `W` need to be part of the sensitivity list; else simulation and synthesis will have different behavior. Change `always @(En)` to `always @(*)` – Greg Dec 09 '16 at 04:53
  • @Zebs See latest edit. There are some other notes you should see. – skrrgwasme Dec 09 '16 at 17:29