2017-09-25 5 views
0

J'essaye de développer un code qui agit comme une calculatrice logique; J'ai réussi à compiler le code et le testbench sans aucune erreur. Voici le code:Système Verilog Testbench waveforms aucune donnée

module AriLogCal(
        input logic [3:0] OpA, OpB, //Operands A and B. The two numbers we will operate on. 
        input logic [2:0] DoOpt,  //Operator. Determines the operation we will do. 
        input logic EqualTo, AC,  //Interrupts. AC resets, EqualTo transfers data to display. 
        output logic [6:0] S2, S1, S0 //Seven-Segement LEDS. Shows each digit separately. 
       ); 

logic [7:0] result;          //Result. 
Mathematical operation result data is stored here. 
logic [3:0] D2, D1, D0;         //Digits. Determines 
the number/symbol/deactivation for each respective SevenSeg. 

always begin 
if(AC)begin //Makes all the numbers display 0 if AC returns TRUE 
result=8'b00000000; 
S0=7'b1111110; 
S1=7'b1111110; 
S2=7'b1111110;   
end 
else if(EqualTo)begin //Does this stuff if EqualTo returns TRUE 

//Part 1: Operation. Decides the relationship between Operand A and B and stores data under "result" 
case(DoOpt) 
3'b000:result=OpA+OpB; //Addition 
3'b001:begin    //Subtraction 
    if(OpB>OpA) 
     result=OpB-OpA; 
    else 
     result=OpA-OpB; 
end 
3'b010:result=OpA*OpB; //Multiplication 
3'b011:begin    //Division 
    if(OpB) 
     result=OpA/OpB; 
    else 
     result=0; 
end 
3'b100:begin 
    if(OpA&&OpB)    //Logical AND 
     result=8'b00000001; 
    else 
     result=8'b00000000; 
end 
3'b101:begin 
    if(OpA||OpB)    //Logical OR 
     result=8'b00000001; 
    else result=8'b00000000; 
end 
endcase 

//Part 2: Digits. Dissects the value of "result" into its decimal digits and stores them in logic "D" 
if(!OpB&&DoOpt==3'b011)  //This will show "Err" on LED displays 
D0=4'b1010; 
else if(result<10)begin //Single Digit. S1 and S2 is temporarily set to zero 
D0=result; 
D1=4'b0000; 
D2=4'b0000; 
end 
else if(result<100)begin //Double digit. S2 is temporarily set to zero 
D0=result%10; 
D1=result/10; 
D2=4'b0000; 
end 
else begin     //Triple digit. 
D2=result/100; 
result=result%100; 
D1=result/10; 
D0=result%10; 
end 


//Part 3: Blanks. Adds blanks and negative sign depending on operation type, according to requirements 
case(DoOpt) 
3'b000:D2=4'b1011;  //Addition deactivates S2 
3'b001:begin    
if(OpB>OpA)     //Subtraction deactivates or shows negative sign 
for S2 
    D2=4'b1100; 
else 
    D2=4'b1011; 
end 
3'b011:begin     //Multiplcation is skipped. 
if(!OpB)begin    //Division has two options: 
    D0=4'b1010;    //If divider is 0, this will show "Err" on LED 
displays 
    D1=4'b1010; 
    D2=4'b1010; 
end else      //Otherwise, S2 is deactivated 
D2=4'b0000; 
end 
3'b100:begin    //Logical AND deactivates S2 and S1 
    D2=4'b1011; 
    D1=4'b1011; 
end 
3'b101:begin    //Logical OR deactivates S2 and S1 
    D2=4'b1011; 
    D1=4'b1011; 
end 
endcase 

//Part 4: Display. Prints the digits from "D" onto its respective Seven Segment LED S 
case(D0) 
4'b1010: S0<=7'b0000101; //D0=10 means S0 displays R 
4'b1001: S0<=7'b1110011; //9 
4'b1000: S0<=7'b1111111; //8 
4'b0111: S0<=7'b1110000; //7 
4'b0110: S0<=7'b1011111; //6 
4'b0101: S0<=7'b1011011; //5 
4'b0100: S0<=7'b0110011; //4 
4'b0011: S0<=7'b1111001; //3 
4'b0010: S0<=7'b1101101; //2 
4'b0001: S0<=7'b0110000; //1 
4'b0000: S0<=7'b1111110; //0 
endcase 
case(D1) 
4'b1011: S1<=7'b0000000; //D1=11 means S1 deactivates 
4'b1010: S1<=7'b0000101; //D1=10 means S1 displays R 
4'b1001: S1<=7'b1110011; //9 
4'b1000: S1<=7'b1111111; //8 
4'b0111: S1<=7'b1110000; //7 
4'b0110: S1<=7'b1011111; //6 
4'b0101: S1<=7'b1011011; //5 
4'b0100: S1<=7'b0110011; //4 
4'b0011: S1<=7'b1111001; //3 
4'b0010: S1<=7'b1101101; //2 
4'b0001: S1<=7'b0110000; //1 
4'b0000: S1<=7'b1111110; //0 
endcase 
case(D2) 
4'b1100: S2<=7'b0000001; //D2=12 means S2 shows negative sign 
4'b1011: S2<=7'b0000000; //D2=11 means S2 deactivates 
4'b1010: S2<=7'b1001111; //D2=10 means S2 displays E 
4'b1001: S2<=7'b1110011; //9 
4'b1000: S2<=7'b1111111; //8 
4'b0111: S2<=7'b1110000; //7 
4'b0110: S2<=7'b1011111; //6 
4'b0101: S2<=7'b1011011; //5 
4'b0100: S2<=7'b0110011; //4 
4'b0011: S2<=7'b1111001; //3 
4'b0010: S2<=7'b1101101; //2 
4'b0001: S2<=7'b0110000; //1 
4'b0000: S2<=7'b1111110; //0 
endcase 
end 
end 
endmodule 

et voici le banc d'essai en cours (ce qui est une version plus courte, je suis toujours en essayant de trouver le problème derrière cette)

`timescale 1ns/1ps 
module AriLogCal_tb; 
logic [3:0] in_OpA; 
logic [3:0] in_OpB; 
logic [2:0] in_DoOpt; 
logic in_EqualTo; 
logic in_AC; 
logic [6:0] out_S2, out_S1, out_S0; 

AriLogCal AriLogCal_inst0(.OpA(in_OpA), .OpB(in_OpB), .DoOpt(in_DoOpt), 
.EqualTo(in_EqualTo), .AC(in_AC), .S2(out_S2), .S1(out_S1), .S0(out_S0)); 

initial begin 
in_EqualTo=1'b0; 
in_AC=1'b0; 


in_OpA = 4'b0111; in_OpB = 4'b0010; in_DoOpt = 3'b000; 
in_EqualTo = 1'b0;#100; 

$finish; 

end 
endmodule 

Ces deux fichiers sont en mesure compiler individuellement avec succès, sans erreurs. Cependant, lorsque je tente de les compiler dans le simulateur RTL, je reçois ces résultats:

https://drive.google.com/file/d/0By4LCb9TUml0WWVsZEYtcG03LVk/view?usp=sharing

Pourquoi ai-je encore « Aucune donnée » dans mes résultats, malgré la compilation réussie? Une aide immédiate sera appréciée. Merci d'avance.

+0

VCS me donne un avertissement sur votre 1er bloc toujours: 'Ce bloc toujours n'a aucun contrôle d'événement ou des instructions de retard, il pourrait causer une boucle infinie dans la simulation. – toolic

+0

Quelles sont les données que vous attendez? Soyez très précis, comme ... "Je m'attends à ce que la sortie S2 ait la valeur 123 au temps 42ns." – toolic

+0

Dès que j'ajoute un '$ monitor' à votre testbench, ma simulation se bloque. Je pense que l'avertissement VCS est réel. Vous devriez essayer de réparer ce bloc toujours en premier. – toolic

Répondre

0

Il n'y a aucun bloqueur d'événement/heure dans le bloc AriLogCal. always begin est une boucle infinie. Il réévaluera continuellement et empêchera le simulateur de passer au pas de temps suivant.

Il doit être modifié always_comb begin, qui a un blocage du temps hérité et déclenchera uniquement le temps 0 et quand un signal de stimulus change. Alternative vous pouvez utiliser l'auto-sensibilité Verilog @* (ou le @(*)) et changer l'instruction à always @* begin. always_comb est supérieur à always @* car il contient des erreurs de compilation si les besoins de synthèse de base ne sont pas stratifiés (ex: le registre est assigné dans un seul bloc toujours et aucun de blocage ou # dans le bloc toujours).

FYI: vous ne devez pas utiliser d'affectations non bloquantes (<=) dans la logique combinatoire; blocage (=) les affectations sont préférées. Les affectations non bloquantes doivent être utilisées dans always_ff et occasionnellement dans always_latch.