Verilog проблемы со старыми ценностями

Я почти закончил реализацию 5-этапного конвейерного процессора Mips на плате FPGA (стартовый комплект Spartan 3E). Но у одного модуля есть критическая проблема.

Эта проблема заключается в том, что когда mMdule принимает данные из входного сигнала, модуль принимает старые значения. Этот модуль является регистром, который является наиболее важной частью процессора.

вот скриншот (Isim): http://cfile8.uf.tistory.com/original/2441AB3351B74AD217FE01

Серая стрелка - это то, что я конструирую (то, что я хочу).

Но модуль работает как красная стрелка.

Модуль определить

(When reg_write is true) and (Clk is true-not show in screenshot)
register[write_reg]=write_data;

У меня есть собственная плата FPGA (стартовый комплект Spartan 3E)

Реализую на борту только этот модуль. Я сделал signal(Clk, signal. write_reg, write_data) со встроенным sw0 ~ 4. (хотя clk)

и тогда он работает!

нет проблем.

но при использовании этого модуля в дизайне всего ЦП.

Модуль Возникла проблема старых значений.

Вот весь источник

module reg1(Reset, Clk, read_reg1, read_reg2, write_reg, write_data, reg_write, read_data1, read_data2
);

 input Reset;
 input Clk;
 input reg_write;
input [4:0] read_reg1, read_reg2, write_reg; 
 input [31:0] write_data;    
 output [31:0] read_data1;
 output [31:0] read_data2;

 reg [31:0] register [11:0];     
 reg [31:0] read_data1_reg;
reg [31:0] read_data2_reg;
 wire [31:0] read_data1=read_data1_reg;
 wire [31:0] read_data2=read_data2_reg;

always @(reg_write or Reset or read_reg1 or read_reg2)
 begin
 if(reg_write == 1'b0 )
  begin
    case(read_reg1)
    5'b00000: read_data1_reg=register[0];
    5'b00001: read_data1_reg=register[1];
    5'b00010: read_data1_reg=register[2];
    5'b00011: read_data1_reg=register[3];
    5'b00100: read_data1_reg=register[4];
    5'b00101: read_data1_reg=register[5];
    5'b00110: read_data1_reg=register[6];
    5'b00111: read_data1_reg=register[7];
    5'b01000: read_data1_reg=register[8];
    5'b01001: read_data1_reg=register[9];
    5'b01010: read_data1_reg=register[10];
    5'b01011: read_data1_reg=register[11];
    default: read_data1_reg=32'h00000000;
    endcase

    case(read_reg2)
    5'b00000: read_data2_reg=register[0];
    5'b00001: read_data2_reg=register[1];
    5'b00010: read_data2_reg=register[2];
    5'b00011: read_data2_reg=register[3];
    5'b00100: read_data2_reg=register[4];
    5'b00101: read_data2_reg=register[5];
    5'b00110: read_data2_reg=register[6];
    5'b00111: read_data2_reg=register[7];
    5'b01000: read_data2_reg=register[8];
    5'b01001: read_data2_reg=register[9];
    5'b01010: read_data2_reg=register[10];
    5'b01011: read_data2_reg=register[11];
    default: read_data2_reg=32'h00000000;

    endcase
  end
 else
 begin
    if(Clk==1'b1)
        case(write_reg)
        5'b00000: register[0] = write_data;
        5'b00001: register[1] = write_data;
        5'b00010: register[2] = write_data;
        5'b00011: register[3] = write_data;
        5'b00100: register[4] = write_data;
        5'b00101: register[5] = write_data;
        5'b00110: register[6] = write_data;
        5'b00111: register[7] = write_data;
        5'b01000: register[8] = write_data;
        5'b01001: register[9] = write_data;
        5'b01010: register[10] = write_data;
        5'b01011: register[11] = write_data;
        default: register[0] = register[0];
        endcase
else
    begin
    //read_data1_reg = register[read_reg1];
    //read_data2_reg = register[read_reg2];
    case(read_reg1)
    5'b00000: read_data1_reg=register[0];
    5'b00001: read_data1_reg=register[1];
    5'b00010: read_data1_reg=register[2];
    5'b00011: read_data1_reg=register[3];
    5'b00100: read_data1_reg=register[4];
    5'b00101: read_data1_reg=register[5];
    5'b00110: read_data1_reg=register[6];
    5'b00111: read_data1_reg=register[7];
    5'b01000: read_data1_reg=register[8];
    5'b01001: read_data1_reg=register[9];
    5'b01010: read_data1_reg=register[10];
    5'b01011: read_data1_reg=register[11];
    default: read_data1_reg=32'h00000000;
    endcase

    case(read_reg2)
    5'b00000: read_data2_reg=register[0];
    5'b00001: read_data2_reg=register[1];
    5'b00010: read_data2_reg=register[2];
    5'b00011: read_data2_reg=register[3];
    5'b00100: read_data2_reg=register[4];
    5'b00101: read_data2_reg=register[5];
    5'b00110: read_data2_reg=register[6];
    5'b00111: read_data2_reg=register[7];
    5'b01000: read_data2_reg=register[8];
    5'b01001: read_data2_reg=register[9];
    5'b01010: read_data2_reg=register[10];
    5'b01011: read_data2_reg=register[11];
    default: read_data2_reg=32'h00000000;

    endcase
    end

 end


  if(Reset)
     begin
     register[0] = 32'h00000000;
     register[1] = 32'h00000000;
     register[2] = 32'h00000000;
     register[3] = 32'h00000000;
     register[4] = 32'h00000000;
     register[5] = 32'h00000000;
     register[6] = 32'h00000000;
     register[7] = 32'h00000000;
     register[8] = 32'h00000000;
     register[9] = 32'h00000000;
     register[10] = 32'h00000000;
     register[11] = 32'b00000000000000000000000110010000;


     case(read_reg1)
    5'b00000: read_data1_reg=register[0];
    5'b00001: read_data1_reg=register[1];
    5'b00010: read_data1_reg=register[2];
    5'b00011: read_data1_reg=register[3];
    5'b00100: read_data1_reg=register[4];
    5'b00101: read_data1_reg=register[5];
    5'b00110: read_data1_reg=register[6];
    5'b00111: read_data1_reg=register[7];
    5'b01000: read_data1_reg=register[8];
    5'b01001: read_data1_reg=register[9];
    5'b01010: read_data1_reg=register[10];
    5'b01011: read_data1_reg=register[11];
    default: read_data1_reg=32'h00000000;
    endcase

    case(read_reg2)
    5'b00000: read_data2_reg=register[0];
    5'b00001: read_data2_reg=register[1];
    5'b00010: read_data2_reg=register[2];
    5'b00011: read_data2_reg=register[3];
    5'b00100: read_data2_reg=register[4];
    5'b00101: read_data2_reg=register[5];
    5'b00110: read_data2_reg=register[6];
    5'b00111: read_data2_reg=register[7];
    5'b01000: read_data2_reg=register[8];
    5'b01001: read_data2_reg=register[9];
    5'b01010: read_data2_reg=register[10];
    5'b01011: read_data2_reg=register[11];
    default: read_data2_reg=32'h00000000;
    endcase
     //
     end
    else
    begin
    register[0] = register[0];
    register[1] = register[1];
    register[2] = register[2];
    register[3] = register[3];
    register[4] = register[4];
    register[5] = register[5];
    register[6] = register[6];
    register[7] = register[7];
    register[8] = register[8];
    register[9] = register[9];
    register[10] = register[10];
    register[11] = register[11];

            case(read_reg1)
    5'b00000: read_data1_reg=register[0];
    5'b00001: read_data1_reg=register[1];
    5'b00010: read_data1_reg=register[2];
    5'b00011: read_data1_reg=register[3];
    5'b00100: read_data1_reg=register[4];
    5'b00101: read_data1_reg=register[5];
    5'b00110: read_data1_reg=register[6];
    5'b00111: read_data1_reg=register[7];
    5'b01000: read_data1_reg=register[8];
    5'b01001: read_data1_reg=register[9];
    5'b01010: read_data1_reg=register[10];
    5'b01011: read_data1_reg=register[11];
    default: read_data1_reg=32'h00000000;
    endcase

    case(read_reg2)
    5'b00000: read_data2_reg=register[0];
    5'b00001: read_data2_reg=register[1];
    5'b00010: read_data2_reg=register[2];
    5'b00011: read_data2_reg=register[3];
    5'b00100: read_data2_reg=register[4];
    5'b00101: read_data2_reg=register[5];
    5'b00110: read_data2_reg=register[6];
    5'b00111: read_data2_reg=register[7];
    5'b01000: read_data2_reg=register[8];
    5'b01001: read_data2_reg=register[9];
    5'b01010: read_data2_reg=register[10];
    5'b01011: read_data2_reg=register[11];
    default: read_data2_reg=32'h00000000;
    endcase
    end
  end



endmodule

person user1697281    schedule 11.06.2013    source источник


Ответы (1)


Первая проблема, clk нет в вашем списке чувствительности блока always, но вы используете его в одном из операторов if.

Больше беспокоит кодировка всего этого блока. Когда вам нужны регистры, вы вводите защелки. Первое, что нужно исправить, это то, что вы используете блокирующие назначения «=», когда вам нужны неблокирующие назначения «‹ = ». Вторая вещь, которую вы должны изменить, - это вытащить назначение регистров и сделать это в другом всегда блоке. это будет выглядеть примерно так:

always@(posedge clk, posedge reset)
begin 
    if(reset)
        reset data
    else if( write_en0
        set regs to writedata
    else 
        reg <= reg 
end 

always@(posedge clk, posedge reset)
begin 
    read_data1 data
end 

always@(posedge clk, posedge reset)
begin 
    read_data2 data
end 

эта статья хорошо объясняет это: http://www-inst.eecs.berkeley.edu/~cs152/fa04/handouts/CummingsHDLCON1999_BehavioralDelays_Rev1_1.pdf

person alex_milhouse    schedule 11.06.2013
comment
сначала разница о ‹=, = - person user1697281; 14.06.2013