I'm new to Verilog. When I try to write code for a finite state machine. I get :
[Synth 8-434] mixed level sensitive and edge triggered event controls are not supported for synthesis
Here is my code:
module controller1(x, clk, s, v);
input x;
input clk;
output s;
output v;
reg [2:0] state;
reg s;
reg v;
always # (negedge clk or x) begin
case (state)
3'b0 : begin
state <= x ? 3'b1 : 3'b10;
s = x ? 0 : 1;
v = 0;
end
3'b10 : begin
state <= x ? 3'b11 : 3'b101;
s = x ? 0 : 1;
v = 0;
end
3'b1 : begin
state <= 3'b11;
s = x ? 1 : 0;
v = 0;
end
3'b101 : begin
state <= 3'b100;
s = x ? 1 : 0;
v = 0;
end
3'b11 : begin
state <= x ? 3'b111 : 3'b100;
s = x ? 0 : 1;
v = 0;
end
3'b100 : begin
state <= 3'b0;
s = x ? 1 : 0;
v = 0;
end
3'b111 : begin
state <= 3'b0;
s = x ? 0 : 1;
v = x ? 1 : 0;
end
endcase
end
endmodule
The question is:
A sequential circuit has
one 1-bit input (X)
a clock input (CLK)
two 1-bit outputs (S and V)
X represents a 4-bit binary number N. The 4-bit number will input one digit a time and start from the least significant bit (LSB).
S represents a 4-bit binary number equal to N + 3. The LSB of S will be output first
when the fourth bit input occurs, V = 1 if N + 3 is too large to be
represented by 4 bits; otherwise, V = 0.
circuit always resets after the fourth bit of X is received. Assume the sequential circuit is implemented with the following
state table.
The outputs are (S,V). All state changes occur on the falling edge of the clock pulse.
If my code has problem to get the required result, please point out. Thanks!
Basically every always block is describing a group of flip-flop, a group of latch, or a block of combinational circuit.
In your code you have mixed edge and level sensitivity by using 'negedge clock' and 'x'. If your FSM is sensitive to only falling edge of clock then remove 'x' from sensitivity list of always block.
Mixed sensitive list of levels and edges is not synthesizable, because a flip-flop cannot be edge-tiggered and level-triggered at the same time.
Check this link:
Synthesis of `always` blocks
Related
I am trying to implement 4x1 multiplexer in Verilog. I want to connect enable (en) as a port which input '1'(high) can ON the MUX and '0'(low) turn OFF this multiplexer.
Please suggest some modifications in my code.
Thanks in Advance.
module mux_4_to_1(
input d,c,b,a, //Inputs
input s1,s0, //Select Lines
input en, //enable
output reg y //output
);
always # (*)
begin
case (s0 | s1)
2'b00 : y <= a;
2'b01 : y <= b;
2'b10 : y <= c;
2'b11 : y <= d;
default : y <= 0;
endcase
end
endmodule
You want en to act as a global switch to turn on or off the mux, so it gets the highest priority.
always # (*)
begin
if (en) begin
case ({s0, s1}) // pay attention here
2'b00 : y = a;
2'b01 : y = b;
2'b10 : y = c;
2'b11 : y = d;
default : y = 0;
endcase
end
else begin
y = 1'b0; // your question didn't specify the expected output when OFF
end
end
Please notice I've changed case (s0 | s1) to case ({s0, s1}).
s0 | s1 returns a 1-bit wide result, while you need the concatenation of s0 and s1.
Also, I replaced all NBA <= by BA =.
And, the default branch actually couldn't happen in silicon because you've specified all possible combinations. But if you think it maybe helpful in simulation, you may leave it.
In the following Verilog module, I'd like to understand why the blocking assignment using concatenation doesn't give the same result as the 2 commented out blocking assignments.
When I run the program on the FPGA, it gives the expected result with the 2 blocking assignments (the leds blink), but not with the blocking assignment using concatenation (the leds stay off).
Bonus points for answers pointing to the Verilog specification explaining what is at play here!
/* Every second, the set of leds that are lit will change */
module blinky(
input clk,
output [3:0] led
);
reg [3:0] count = 0;
reg [27:0] i = 0;
localparam [27:0] nTicksPerSecond = 100000000;
assign led = {count[3],count[2],count[1],count[0]};
always # (posedge(clk)) begin
// This works:
//count = i==nTicksPerSecond ? (count + 1) : count;
//i = i==nTicksPerSecond ? 0 : i+1;
// But this doesn't:
{count,i} = i==nTicksPerSecond ?
{count+1, 28'b0 } :
{count , i+1};
end
endmodule
PS: I use Vivado 2018.2
The reason is because the widths of count+1 and i+1 are both 32 bits. An unsized number is 32 bits wide (1800-2017 LRM section 5.7.1) and the width of the addition operator is the size of the largest operand (LRM section 11.6.1). To make your code work, add a proper size to your numeric literals
{count,i} = i==nTicksPerSecond ?
{count+4'd1, 28'b0 } :
{count , i+28'd1};
A simpler way to write this code is
always # (posedge clk)
if (i== nTicksPerSecond)
begin
count <= count + 1;
i <= 0;
end
else
begin
i <= i + 1;
end
I am working on an assignment and am a little lost and don't really know how to get started. I need to implement the following flags in a 32Bit ALU:
• Z ("Zero"): Set to 1 ("True") if the result of the operation is zero
• N ("Negative"): Set to 1 ("True") if the first bit of the result is 1, which indicates a negative number
• O ("Overflow"): Set to 1 ("True") to indicate that the operation overflowed the bus width.
Additionally, a comparison function that compares input a to input b and then set one of three flags:
• LT if input a is less than input b
• GT if input a is greater than input b
• EQ if input a is equal to input b
I need to modify this ALU to include the three flags and comparison outputs then change the test bench to test for all of these modifications.
This was all the information I received for this assignment and there is no textbook or any other resources really. It's an online class, and I cannot get a response from my instructor. So I am a little confused as to how to get started. I am still a total newbie when it comes to digital logic so please bear with me. I just need some help understanding how these flags and comparison works. If any one can explain this a little better to me as far as how they work and what they do, and possibly how I would implement them into the ALU and testbench, I would really appreciate it.
I don't expect anyone to do my assignment, I really just need help understanding it.
ALU
module alu32 (a, b, out, sel);
input [31:0] a, b;
input [3:0] sel;
output [31:0] out,
reg [31:0] out;
//Code starts here
always #(a, b, sel)
begin
case (sel)
//Arithmetic Functions
0 : out <= a + b;
1 : out <= a - b;
2 : out <= b - a;
3 : out <= a * b;
4 : out <= a / b;
5 : out <= b % a;
//Bit-wise Logic Functions
6 : out <= ~a; //Not
7 : out <= a & b; //And
8 : out <= a | b; //Or
9 : out <= a ^ b; //XOR
10 : out <= a ^~ b; //XNOR
//Logic Functions
11 : out <= !a;
12 : out <= a && b;
13 : out <= a || b;
default: out <= a + b;
endcase
end
endmodule
ALU Testbench
module alu32_tb();
reg [31:0] a, b;
reg [3:0] sel;
wire [31:0] out;
initial begin
$monitor("sel=%d a=%d b=%d out=%d", sel,a,b,out);
//Fundamental tests - all a+b
#0 sel=4'd0; a = 8'd0; b = 8'd0;
#1 sel=4'd0; a = 8'd0; b = 8'd25;
#1 sel=4'd0; a = 8'd37; b = 8'd0;
#1 sel=4'd0; a = 8'd45; b = 8'd75;
//Arithmetic
#1 sel=4'd1; a = 8'd120; b = 8'd25; //a-b
#1 sel=4'd2; a = 8'd30; b = 8'd120; //b-a
#1 sel=4'd3; a = 8'd75; b = 8'd3; //a*b
#1 sel=4'd4; a = 8'd75; b = 8'd3; //a/b
#1 sel=4'd5; a = 8'd74; b = 8'd3; //a%b
//Bit-wise Logic Functions
#1 sel=4'd6; a = 8'd31; //Not
#1 sel=4'd7; a = 8'd31; b = 8'd31; //And
#1 sel=4'd8; a = 8'd30; b = 8'd1; //Or
#1 sel=4'd9; a = 8'd30; b = 8'd1; //XOR
#1 sel=4'd10; a = 8'd30; b = 8'd1; //XNOR
//Logic Functions
#1 sel=4'd11; a = 8'd25; //Not
#1 sel=4'd12; a = 8'd30; b = 8'd0; //And
#1 sel=4'd13; a = 8'd0; b = 8'd30; //Or
#1 $finish;
end
alu32 myalu (.a(a), .b(b), .out(out), .sel(sel));
endmodule
You can add these flag outputs to the design. Like the following. Simply connect them in testbench.
// In design:
output zero;
output overflow;
output negative;
// In testbench:
wire zero,overflow,negative;
alu32 myalu (.a(a), .b(b), .out(out), .sel(sel), .zero(zero), .overflow(overflow),.negative(negative));
For logic part, you can do it with continuous assignments. You may need to add some logic for using these flags only during certain values of sel.
Z ("Zero"): Set to 1 ("True") if the result of the operation is zero
So, we can have condition like all the bits of out must be zero. This can be done in many other ways.
// Bit wise OR-ing on out
assign zero = ~(|out);
O ("Overflow"): Set to 1 ("True") to indicate that the operation overflowed the bus width.
According to this description and the code shown, you simply want carry flag here.That is, a signed extension of addition operation. Refer to this page on WikiPedia for overflow condition.
But, Overflow condition is not the same as the carry bit. Overflow represents data loss while carry represents a bit used for calculation in next stage.
So, doing something like following may be useful:
// Extend the result for capturing carry bit
// Simply use this bit if you want result > bus width
{carry,out} <= a+b;
// overflow in signed arithmetic:
assign overflow = ({carry,out[31]} == 2'b01);
N ("Negative"): Set to 1 ("True") if the first bit of the result is 1, which indicates a negative number
Again this is simply the MSB of the out register. But, the underflow condition is entirely a different thing.
// Depending on sel, subtraction must be performed here
assign negative = (out[31] == 1 && (sel == 1 || sel == 2));
Also, simple condition like assign lt = (a<b) ? 1 : 0; and others can detect the input LT, GT and EQ conditions.
Refer the answer here for the overflow/underflow flag understanding. Overflow-Carry link may also be useful.
Refer Carryout-Overflow, ALU in Verilog and ALU PDF for further information about ALU implementation.
My project is to design a verilog code that gives an output on the 7segments (HEX0,HEX1,HEX2,HEX3) and output must increase when the button KEY0 is pressed on the board 1 by 1, and decrease when the button KEY1 is pressed using Altera Board (Cyclone II-EP2C35F672).
I achieve to increase 1 by 1 but when I try to decrease with the same logic, I take irrelevant outputs. Is it possible to give me a way solving the problem.
My verilog code is that:
module sevensegment (KEY,HEX0,HEX1,HEX2,HEX3);
input [3:0]KEY;
output [0:6]HEX0;
output [0:6]HEX1;
output [0:6]HEX2;
output [0:6]HEX3;
counter D1(~KEY,HEX0,HEX1,HEX2,HEX3);
endmodule
module counter(in,out,out1,out2,out3);
input [3:0]in;
output [6:0]out;
output [6:0]out1;
output [6:0]out2;
output [6:0]out3;
reg[15:0] tmp;
always #(posedge in)
begin
if(~in[0])
begin
tmp <= tmp + 1'b1;
end
else if(~in[1])
begin
tmp <= tmp - 1'b1;
end
end
displaysevensegment first_digit(tmp[3:0],out);
displaysevensegment second_digit(tmp[7:4],out1);
displaysevensegment third_digit(tmp[11:8],out2);
displaysevensegment fourth_digit(tmp[15:12],out3);
endmodule
module displaysevensegment(in,out);
// abcdefg
parameter BLANK = 7'b1111111;
parameter ZERO = 7'b0000001;
parameter ONE = 7'b1001111;
parameter TWO = 7'b0010010;
parameter THREE = 7'b0000110;
parameter FOUR = 7'b1001100;
parameter FIVE = 7'b0100100;
parameter SIX = 7'b0100000;
parameter SEVEN = 7'b0001111;
parameter EIGHT = 7'b0000000;
parameter NINE = 7'b0000100;
parameter TEN = 7'b0001000;
parameter ELEVEN = 7'b1100000;
parameter TWELVE = 7'b0110001;
parameter THIRTEEN = 7'b1000010;
parameter FOURTEEN = 7'b0110000;
parameter FIFTEEN = 7'b0111000;
input [3:0]in;
output [6:0]out;
assign out = (in == 0) ? ZERO:
(in == 1) ? ONE:
(in == 2) ? TWO:
(in == 3) ? THREE:
(in == 4) ? FOUR:
(in == 5) ? FIVE:
(in == 6) ? SIX:
(in == 7) ? SEVEN:
(in == 8) ? EIGHT:
(in == 9) ? NINE:
(in == 10) ? TEN:
(in == 11) ? ELEVEN:
(in == 12) ? TWELVE:
(in == 13) ? THIRTEEN:
(in == 14) ? FOURTEEN:
(in == 15) ? FIFTEEN:BLANK;
endmodule
The simulate will not recognize the raising edge of in[1] when the sensitivity list is describes as posedge in. Only the LSB will be monitored. Instead use a bitwise operation to detect when a key is pressed and use this as the clocking signal.
wire gen_clk = |in; // bitwise OR
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
wire gen_clk = ∈ // bitwise AND
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
Side note: Deep nested muxes often result in lower performance more area then a case statement. This is because most synthesizer will not optimize inline muxes (?:). Recommend re-coding displaysevensegment with a case statement like:
input [3:0] in;
output [6:0] out;
reg [6:0] out; // out needs to be a reg
always #* begin
case(in)
4'h0 : out = ZERO;
4'h1 : out = ONE;
// ...
4'hE : out = FOURTEEN;
4'hF : out = FIFTEEN;
default: out = BLANK;
endcase
end
I know how to design a 4x4 array multiplier , but if I follow the same logic , the coding becomes tedious.
4 x 4 - 16 partial products
64 x 64 - 4096 partial products.
Along with 8 full adders and 4 half adders, How many full adders and half adders do I need for 64 x 64 bit. How do I reduce the number of Partial products? Is there any simple way to solve this ?
Whenever tediously coding a repetitive pattern you should use a generate statement instead:
module array_multiplier(a, b, y);
parameter width = 8;
input [width-1:0] a, b;
output [width-1:0] y;
wire [width*width-1:0] partials;
genvar i;
assign partials[width-1 : 0] = a[0] ? b : 0;
generate for (i = 1; i < width; i = i+1) begin:gen
assign partials[width*(i+1)-1 : width*i] = (a[i] ? b << i : 0) +
partials[width*i-1 : width*(i-1)];
end endgenerate
assign y = partials[width*width-1 : width*(width-1)];
endmodule
I've verified this module using the following test-bench:
http://svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v
EDIT:
As #Debian has asked for a pipelined version - here it is. This time using a for loop in an always-region for the array part.
module array_multiplier_pipeline(clk, a, b, y);
parameter width = 8;
input clk;
input [width-1:0] a, b;
output [width-1:0] y;
reg [width-1:0] a_pipeline [0:width-2];
reg [width-1:0] b_pipeline [0:width-2];
reg [width-1:0] partials [0:width-1];
integer i;
always #(posedge clk) begin
a_pipeline[0] <= a;
b_pipeline[0] <= b;
for (i = 1; i < width-1; i = i+1) begin
a_pipeline[i] <= a_pipeline[i-1];
b_pipeline[i] <= b_pipeline[i-1];
end
partials[0] <= a[0] ? b : 0;
for (i = 1; i < width; i = i+1)
partials[i] <= (a_pipeline[i-1][i] ? b_pipeline[i-1] << i : 0) +
partials[i-1];
end
assign y = partials[width-1];
endmodule
Note that with many synthesis tools it's also possible to just add (width) register stages after the non-pipelined adder and let the tools register balancing pass do the pipelining.
[how to] reduce the number of partial products?
A method somewhat common used to be modified Booth encoding:
At the cost of more complicated addend selection, it at least almost halves their number.
In its simplest form, considering groups of three adjacent bits (overlapping by one) from one of the operands, say, b, and selecting 0, a, 2a, -2a or -a as an addend.
The code below generates only half of expected the output.
module arr_multi(a, b, y);
parameter w = 8;
input [w-1:0] a, b; // w-width
output [(2*w)-1:0] y; // p-partials
wire [(2*w*w)-1:0] p; //assign width as input bits multiplied by
output bits
genvar i;
assign p[(2*w)-1 : 0] = a[0] ? b : 0; //first output size bits
generate
for (i = 1; i < w; i = i+1)
begin
assign p[(w*(4+(2*(i-1))))-1 : (w*2)*i] = (a[i]?b<<i :0) + p[(w*(4+(2*
(i-2))))-1 :(w*2)*(i-1)];
end
endgenerate
assign y=p[(2*w*w)-1:(2*w)*(w-1)]; //taking last output size bits
endmodule