Мои утверждения выглядят как XXXXXX вместо значения по умолчанию в инструкции case. в Verilog HDL - PullRequest
0 голосов
/ 29 мая 2020

Изменить: я забыл добавить ai = i + 1, код работает, но он все еще не работает для значения 0, что я пытаюсь исправить сейчас.

Я пытаюсь смоделировать светодиодный массив 3 di git 7 сегментов, поэтому я использую постоянный ввод (в данном случае 1,2,3 ...), который находится в двоичном формате, и превращаю его в Binary-Coded-Decimal, а затем поместил его в модуль для сегмента 7, чтобы получить число для отображения.

Мой код продолжает отображать XXXXXXX вместо 1111111, который должен отображаться как оператор case по умолчанию. Если кто-нибудь знает, что может быть причиной этого, дайте мне знать.

вот код, который я использую для отображения результатов

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);

это 2 функции, которые я использую в своих код

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

и семисегментный модуль:

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

1 Ответ

4 голосов
/ 29 мая 2020

Ваша программа полна ошибок Verilog и программирования. Я заметил несколько:

  1. оператор & не то же самое, что оператор && в операторах if. Он работает по-другому и имеет другой порядок приоритета. Итак, ваши операторы if просто не работают правильно в любом случае. Вы использовали & во всех условных операторах.

  2. в вашем операторе i>0 & i<9 должно выглядеть как i >= 0 && i < 9. Отсутствующий >= вызвал вашу проблему x (в сочетании с №1).

  3. вы неправильно использовали blocking присвоения в последовательных логах c из double_dabble. Некоторые из них должны быть non-blocking.

  4. Вы неправильно использовали инициализацию переменной. Это может работать в симуляции и некоторых fpga, но не работает в реальном мире. Вам нужен сброс.

  5. вы неправильно использовали non-blocking присвоение в комбинационной логике c из m_7segled все они должны быть blocking.

в ответ на комментарий: Об инициализации reg.

Использование таких операторов, как reg[3:0] i=0;, хотя и допустимо в Verilog, может вызвать проблемы с синтезом. Они могут быть правильно синтезированы в некоторых fpga или системах эмуляции, но не будут синтезированы инструментами синтеза schemati c. Итак, в общем, вы должны использовать сигнал сброса и инициализировать эти переменные с помощью сброса, примерно так:

always @(posedge clk) begin
    if (reset)
       i <= 0;
    else 
       i <= i + 1;
end
...