0

Edit:I forgot to add a i =i+1, the code works but it still doesn't work for the 0 value which is what I am trying to fix now.

I am trying to simulate a 3 digit 7segment led array so I'm taking in a constant input(in this case 1,2,3...) which is in binary and turning it into Binary-Coded-Decimal and then putting it in the module for a 7 segment to get the number to display.

My code keeps displaying XXXXXXX instead of the 1111111 which is supposed to display as the default case statement. If anyone knows what might be causing that please let me know.

here is the code I am using to display the results

module m_top();

 reg clk =0;
reg[7:0] eight_bit_value;
wire[3:0] r_in;//ones
wire[3:0] r2_in;//tens
wire[3:0] r3_in;//hundreds
wire [6:0] w_led;
wire [6:0] w2_led;
wire [6:0] w3_led;


integer i;
always#5 clk=~clk;//clock 
initial $display ("        gfedcba  gfedcba");
double_dabble segmentbits(clk,eight_bit_value,r_in,r2_in,r3_in);

initial begin
  eight_bit_value<= 8'd0; i = 0;
  #1 $display("%3d -> %b %b %b %b", i,eight_bit_value, w_led,w2_led,w3_led);
  for(i = 1; i <= 99; i = i + 1) begin
    #1000 eight_bit_value <= eight_bit_value + 1;
    #1000 $display("%3d ->%b %b %b %b", i, eight_bit_value,w_led,w2_led,w3_led);
  end
end

 //double_dabble segmentbits(clk,eight_bit_value,r_in,r2_in,r3_in); 
 m_7segled m_7segled1(r_in, w_led);
 m_7segled m_7segled2(r2_in,w2_led);
 m_7segled m_7segled3(r3_in,w3_led);

these are the 2 functions which I am using in my code

module double_dabble(input clk,
             input  [7:0] original_value, 
             output reg[3:0] ones,
             output reg[3:0] tens,
             output reg[3:0] hundreds);




 reg[3:0] i=0;
  reg[19:0] shift_register =0;

  reg[3:0] temp_ones=0;
  reg[3:0] temp_tens=0;
  reg[3:0] temp_hundreds=0;

  reg[7:0]temp_original_value=0;




 always@(posedge clk)
    begin//as long as value doesnt change)
        if(i==0&(temp_original_value !=original_value))
        begin
        shift_register = 20'd0;
        temp_original_value = original_value;

        //setting up the register to be shifted 
        temp_hundreds = shift_register[19:16];
        temp_tens =shift_register[15:12];
        temp_ones=shift_register[11:8];
        shift_register[7:0] = original_value;
        i=i+1;// I FORGOT TO ADD THIS , NOW I DID AND IT WORKS FOR >0 but not for 0;
         end
        if(i>0 & i<9)
        begin
        //check if they are greater than 5 if so add 3
        if(temp_hundreds>=5) temp_hundreds=temp_hundreds+3;
        if(temp_tens>=5) temp_tens=temp_tens+3;
        if(temp_ones>=5) temp_ones=temp_ones+3;

        shift_register[19:8] = {temp_hundreds,temp_tens,temp_ones};

        shift_register= shift_register<<1;

        temp_hundreds = shift_register[19:16];
        temp_tens =shift_register[15:12];
        temp_ones=shift_register[11:8];
        i=i+1;
        end
         if(i==9)
           begin
           i=0;

           hundreds = temp_hundreds;
           tens=temp_tens;
           ones=temp_ones;
           end
        end
endmodule

and the sevensegment module is this:

module m_7segled (w_in,r_led);

    input wire [3:0] w_in;
    output reg [6:0] r_led;

    always@(*) begin
        case (w_in%10)
            4'd0 : r_led <= 7'b1000000;
            4'd1 : r_led <= 7'b1111001;
            4'd2 : r_led <= 7'b0100100;
            4'd3 : r_led <= 7'b0110000;
            4'd4 : r_led <= 7'b0011001;
            4'd5 : r_led <= 7'b0010010;
            4'd6 : r_led <= 7'b0000010;
            4'd7 : r_led <= 7'b1011000;
            4'd8 : r_led <= 7'b0000000;
            4'd9 : r_led <= 7'b0010000;
            default : r_led <= 7'b1111111;
        endcase
    end
endmodule
Sam
  • 19
  • 6

1 Answers1

4

Your program is full of verilog and programming mistakes. There are few I spotted:

  1. operator & is not the same as operator && in if statements. It works differently and has different precedence order. So, your if statements just do not work correctly in any case. You used & in all conditional statements.

  2. in your statement i>0 & i<9 should look like i >= 0 && i < 9. missing >= caused yor x issue (in combination with #1).

  3. you incorrectly used blocking assignments in the sequential logic of double_dabble. Some of them should be non-blocking.

  4. you incorrectly used variable initialization. This might work in simulation and some fpga but does not work in real world. You need a reset.

  5. you incorrectly used non-blocking assignment in combinational logic of m_7segled they all should be blocking.

answering the comment: About reg initialization.

Using statements like reg[3:0] i=0; though is legal in verilog, it can give you synthesis problems. They could be synthesized correctly in some fpga or emulation systems but will not be synthesized by schematic synthesis tools. So, in general you should use a reset signal and initialize those vars with a reset, something like the following:

always @(posedge clk) begin
    if (reset)
       i <= 0;
    else 
       i <= i + 1;
end
Serge
  • 11,616
  • 3
  • 18
  • 28
  • Thanks for your input. I was checking a little bit and I've realized the following: 1.I should use && because it is a Logical Operation and not a logical reduction which I suppose is more like the ones used when masking. 3. I have changed the assignment values to parallel and the counter values to blocking 4. I'm still not sure about the variable initialization , would you mind expanding? 5. I thought since it was a case statement it wouldn't matter. – Sam May 29 '20 at 11:21
  • 1
    I added an explanation about #4. As for #3 and #5, incorrect use of blocking/non-blocking can end up in races and glitches, leading to non-deterministic simulation results and simulation/synthesis mismatches. It is important to follow industry practices about use of different types of assignments. – Serge May 29 '20 at 13:09
  • i just noticed a couple of non-blocking assignments in the initial block.Unless you know exactly what you are doing with non-blocking assignments, do not use them. They are definitely not needed and might cause races in you case. – Serge May 29 '20 at 15:45
  • Thank you for the help , this is my first time writing verilog code as a software developer, I will rething the code throughly and try to fix it in the best way possible. – Sam May 30 '20 at 04:49
  • right, verilog is not a software language and has a different from 'c' set of semantics. You need to write RTL portion from the point of view of a hardware engineer, test bench as a software engineer exposed to hardware and always keep in mind event-driven nature of simulation and related execution scheduling, race conditions and glitches. – Serge May 30 '20 at 12:51