I'm trying to develop a code which acts like a logical calculator; I've managed to compile both the code and the testbench without any errors. Here is the code:
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
and here is the current testbench (this is a shorter version; I'm still trying to find the problem behind this)
`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
Both of these files are able to individually compile successfully, with no errors. However, when I try to compile them in the RTL Simulator, I get these results:
https://drive.google.com/file/d/0By4LCb9TUml0WWVsZEYtcG03LVk/view?usp=sharing
Why do I still get "No Data" in my results, despite successful compilation? Immediate help will be appreciated. Thanks in advance.
There isn't any event/time blockers in AriLogCal
's always block.always begin
is an infinite loop. It will continuously re-evaluate and prevent the simulator from moving to the next time step.
It should be changed always_comb begin
, which has an inherited time blocking and will only trigger the at time 0 and when an stimulus signal changes. Alternative you could use the Verilog auto-sensitivity @*
(or the synonymous @(*)
) and change the statement to always @* begin
. always_comb
is superior to always @*
because it with through compiling errors if basic synthesis requirements are not stratified (ex: register is assigned in only one always block and no blocking @
or #
statements in the always block).
FYI: You should not be using non-blocking (<=
) assignments in combinational logic; blocking (=
) assignments are preferred. Non-blocking assignments should be used in always_ff
and the occasional always_latch
.