build a 8bit ALU using verilog - case

I'm trying to build an 8bit datapath in an ALU that can add, sub, OR, AND two operands.
I want to use a case statement for each of the operations in the code but I keep getting error messages.
This is what it looks like so far:
module alu (
input [7:0] xa,xb,
input [7:0] op_sel,
input wire ctrl,
output reg 0Zero, 0Carry,
//0Zero infers latch: can only be assigned to 1/ always reg
output reg [7:0] result_out,
);
always #(*)
8'hE0 :
//4 bit for now
begin
out = 8'b0;
0Carry = 1'b0;
//calculate value
case (1) //alu controlled by ctrl signal
8'hA0: out = xa&xb;
//
8'hB0: (0Carry ,out) = xa+xb;
//
8'hC0: (0Zero , 0Carry, out) = xa-xb;
//
8'hD0: out = ~(xa|xb);
//
endcase
end

Your case expression is 1, you should change that into some variable. Here is an example case statement:
reg [1:0] address;
case (address)
2'b00 : statement1;
2'b01, 2'b10 : statement2;
default : statement3;
endcase
If the address value is 2'b00 then statement1 will be executed. Statement2 is executed when address value equals 2'b01 or 2'b10. Otherwise statement3 is executed.

Related

How to preserve a value in a case statement in verilog

When designing finite state machines in verilog, I find myself writing code like this a lot to preserve a value in a particular state.
always#(state, a, b) begin
case(state) begin
S1: a = b;
S2: a = a; // preserve a;
endcase
end
This is necessary because if I don’t specify a value for each register in the sensitivity list, the compiler will infer a latch. To me this feels like a code smell, but I’m not experienced enough to know for sure. Is this the best way to preserve a value in verilog?
Preserve state means to create a latch, which is a device that do exactly that.
a=a is a null statement and you should not use it at all.
Do not use sensetivity lists in the always block, they are error prone, use #* instead.
And, for latches, you should use non-blocking assignments.
Your latch case statement should look like the following:
always#(*) begin
case(state) begin
S1: a <= b;
S2: // do nothing about 'a', a will not change.
endcase
end
in general the FSM scheme use in industry uses clocks and looks like the following:
always#(posedge clk) begin
case(state) begin
S1: begin
next_state <= S2;
a <= b;
end
S2: // do nothing about 'a', a will not change.
....
endcase
end
assign state = next_state;

Arduino sketch repeats an instruction even when it doesn't have too

I'm programming an Arduino Sketch that in general terms is a calculator that uses 4 numeric systems: decimal, binary, octal and hexadecimal.
When I ask the user for the numeric system he's gonna input the desired system (1 for decimal, 2 for hexadecimal, 3 for octal and 4 for binary) with a keypad, then, after receiving this input, the arduino prints on an LCD the chosen system. But these portion of the code seems to repeat itself indifinitely, without executing the part where the numbers and operands are inputted. I can't input numbers that aren't 1, 2, 3 or 4 and if I press one of these numbers it prints its system, completely ignoring the previous input.
I've tried boolean switches to indicate the program to not run that portion of the code if it has been executed previously but it doesn't seem to work
This is the portion of the code that receives the input and validates it. The switch case repeats itself other 3 times in the other 3 cases, changing the numerical system that is printed.
void loop()
{
char base = calcuShift.getKey();
if (base != NO_KEY && (base == '1' || base == '2' || base == '3' || base == '4')) {
switch (base) {
case '1':
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Sistema");
lcd.setCursor(0,1);
lcd.print("Decimal");
delay(3000);
lcd.clear();
break;
After the switch case it must execute the following code:
char key;
if (digitalRead(A0) == HIGH) {
key = calcuShift.getKey();
} else {
key = calcu.getKey();
}
if (key != NO_KEY &&
(key=='1' || key=='2' || key=='3' || key=='4' || key=='5' || key=='6' || key=='7' || key=='8' || key=='9') &&
base == '1') {
if (inicio == false) {
num1 = num1 + key;
int numLength = num1.length();
lcd.setCursor(15-numLength,0);
lcd.print(num1);
} else {
num2 = num2 + key;
int numLength = num2.length();
lcd.setCursor(15-numLength,1);
lcd.print(num2);
final = true;
}
Obviously including other if conditionals that vary depending on the variable "base" (the one the user inputs at the beginning). If it's 1 (decimal) it accepts numbers 0 through 9, if it's 2 (hexadecimal) it accepts numbers 0 through F etc.
The user inputs his numbers with the variable key. The object calcuShift is just the normal keypad in shift mode, with the letters and other two operands instead of numbers and the multiplication and division operands replaced by power and root operands.
I want my calculator to receive the wanted numeric system, receive numbers in such system and make operations with these numbers, returning an answer in the previously chosen system, but instead just sticks to the input of the variable "base" that dictates the numeric system used.
An Arduino sketch is intended to execute loop() as fast as possible forever and ever.
Anything that is intended to run once after startup should go into setup()
Typically, you define a sort of finite state machine that behaves different whether a user is supposed to enter the number base code or a digit or an operator key. And it stores previous input (the current state) in some global or static variables.
At the end of loop() there's no "program" finish, but it just has checked for all currently possible state changes, stored them and eventually updated the display.
And as loop() is fast enough to react immediately on any button press, it will normally simply do nothing, as no new key is pressed.
If your code does something repeatedly forever but should do that only once, you simply don't store the fact that this was done already. (Or you use the reset button as user interface and allow that "choose number base" only for the setup() phase )

Trying to perform addition of two fractional fixed_point operands in VERILOG, I'm stuck in this error

I'm trying to write a Verilog synthesizable program for adding two fractional fixed_point numbers. This is the test bench:
module sum_test;
// Inputs
reg [12:-20] oper1;
reg [12:-20] oper2;
reg cin;
// Outputs
wire [12:-20] sum_result;
// Instantiate the Unit Under Test (UUT)
sum_fix uut (
.oper1(oper1),
.oper2(oper2),
.cin(cin),
.sum_result(sum_result)
);
initial begin
// Initialize Inputs
oper1 = 0;
oper2 = 0;
cin = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
oper1 = 12.5;
oper2 = 5.4;
end
initial begin
$monitor("oper1=%d,oper2=%d,sum_result=%d \n",oper1,oper2,sum_result);
end
endmodule
/// This is the addition module
module sum_fix(
input [12:-20] oper1,
input [12:-20] oper2,
input cin,
output [12:-20] sum_result
);
assign sum_result = oper1 + oper2 + cin;
endmodule
Simulator print this,
oper1= 0,oper2= 0,sum_result= 0
oper1= 13,oper2= 5,sum_result= 18
It seems I'm not introducing the numbers correctly in the testbench or something, it might be that simulator can't work with this notation? BTW I made this module inspired in the book "Digital Design (Verilog)" of Ashenden. He speaks about this fixed-point fractional notation and even make an addition like me with the operator "+", so I don't know what's wrong, he didn't make test bench for this example, though. Thank you everybody, this forum rocks.
Try using :
reg [32:0] oper1;
reg [32:0] oper2;
instead of :
reg [12:-20] oper1;
reg [12:-20] oper2;
And stimulus is :
oper1 = 12.5 * 2**20; //shift 20 binary places
oper2 = 5.4 * 2**20;

How to use recursive properties in Systemverilog

The module to be verified is as follows...
The module has an input in1 and an output out1, on alternating clock cycles, out1 is the buffered and inverted value of in1.
I tried coding the checker module using a recursive property.
module check (input in1, out1, clk);
property p1(bit state);
bit nxt;
#(posedge clk)
(1 ,nxt=!state) |-> (out1 == (nxt) ? !in1 : in1) and
nexttime p1(nxt);
endproperty
initial assert property(p1(0)) else $fatal(3, "Failed!");
endmodule
However, running the code at edaplayground throws this error...
RROR VCP2000 "Syntax error. Unexpected token: nexttime[_NEXTTIME]. The
'nexttime' is a SystemVerilog keyword and cannot be used as an
identifier.
I know that this assertion can be done without recursion but I would like to use recursion to write it.
The error says that you have used nexttime which is a systemverilog property keyword in a wrong manner. This operator checks that "if the clock ticks once more, then a shall be true at the next clock tick" in the following code
property p1;
nexttime a;
endproperty
By default, the concurrent assertions shall be checked on every clock pulse, so there is no need of recursion here. Roughly, you can do something like this:
module check (input in1, out1, clk);
bit o_nxt;
function bit update(input bit nxt);
o_nxt = nxt;
return 1;
endfunction
property p1(bit state);
bit nxt;
#(posedge clk)
(1 ,nxt=!state) |-> (out1 == (nxt) ? !in1 : in1) and
update(nxt);
endproperty
initial assert property(p1(o_nxt)) else $fatal(3, "Failed!");
endmodule

Asynchronous reset mysteriously setting up output reg

I have this code below:
module timer(
input clk,
input reset,
output reg signal // <--- PROBLEMATIC SIGNAL
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule
and this testbench, which was executed on modelsim:
`timescale 1ns / 1ps
`define PERIOD 20
module timer_tb;
logic clk;
logic reset;
logic signal;
timer inst(
.clk(clk),
.reset(reset),
.signal(signal)
);
initial
begin
clk = 0;
forever clk = #(`PERIOD/2) ~clk;
end
initial
begin
reset = 0; //<--- RESET STARTS CLEANED.
#(`PERIOD)
reset = 1;
#(`PERIOD)
reset = 0;
#(`PERIOD*3)
reset = 1;
#(`PERIOD)
reset = 0;
#(`PERIOD*3)
$display("End of the simulation");
$stop;
end
endmodule
Output reg signal starts HIGH but in the code, this reg depends of reset, and the reset starts DOWN. I don't understand why signal register is HIGH in the beginning of the simulation as the reset starts surely DOWN.
I need the signal starting DOWN and only be set up IF reset go to 1 (condition posedge reset just like my code).
Please take a look on this print of the waveform for clear understanding of my problem.
Your waveform has clock-to-q delay, but your RTL model doesn't have any delay. This implies you are not running RTL simulation. Rather your are running a synthesized gate level simulation or getting output from an FPGA.
Something to consider is that in the test bench, clk and reset start as X not 0. The become 0 at time zero. Verilog allows indeterminate order for parallel process, it is optional to execute an always block at time zero regardless of its sensitivity list, and an X in for a comparison evaluates as true. Depending how the vendor implemented the simulator, it is possible the always block got executed first. reset being X evaluates as true and assigns signal to 1. Then clk and reset are assigned to 0. All of this happens at time 0 and cannot be seen in waveform.
This allowed unpredictability is an unintentional slice of reality. When you first power up a circuit what you initially get may be unpredictable (this is from process variation, physical routing, glitches while the power supply is being ramped, etc. ). You use a reset to get the design into a known state.
If you want to prevent the clk and reset from ever begin X, then change the data-type in the test-bench from logic to bit (note:bit and logic are SystemVerilog). Another option that should work (not 100% guaranteed) is to initialize clk and reset in the same line as it's declaration.
logic clk = 1'b0;
logic reset = 1'b0;
This should work assuming you are running simulation. If you are running on FPGA you cannot guaranty this time zero behavior through changes in your test bench.
The cleanest solution is to start with reset enabled. You should not care what the values are before reset at time zero.
signal has not initial value, so its value at time 0 is undefined. Some simulators initialize it to 0, others to 1, others to X.
Use an initial block to have signal initialized to 0.
module timer(
input clk,
input reset,
output wire signal
);
reg rsignal;
assign signal = rsignal;
initial begin
rsignal = 1'b0;
end
always#(posedge clk or posedge reset)
begin
if(reset)
rsignal <= 1;
else
rsignal <= 0;
end
endmodule
The default value of reg is 'x' or undefined and default value of wire is 'Hi-Z' , so in this case your output (signal) is reg type so simulator took default value accordingly, to get a default value of '0' SystemVerilog(IEEE1800-2012) comes with bit data type, you can try using bit in the output as shown below
module timer(
input clk,
input reset,
output bit signal
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule
EDIT: I am not sure of quartus but conversely you can try initializing the value to 0 or 1 at the output by this method, It should work in Verilog
module timer(
input clk,
input reset,
output reg signal=0
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule

Resources