How to connect enable port to 4x1 MUX in verilog? - verilog

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.

Related

Problem on HDLBits: Exams/m2014 q6c, stuck at gnd

Problem : https://hdlbits.01xz.net/wiki/Exams/m2014_q6c
Here is my code
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
parameter A = 000001, B = 000010, C = 000100, D = 001000,
E = 010000, F = 100000;
reg [2:0] next_state;
always #(*) begin
casez(y)
6'b000001 : next_state <= w ? A : B;
6'b00001z : next_state <= w ? D : C;
6'b0001zz : next_state <= w ? D : E;
6'b001zzz : next_state <= w ? A : F;
6'b01zzzz : next_state <= w ? D : E;
6'b1zzzzz : next_state <= w ? D : C;
default : next_state <= A;
endcase
end
assign Y2 = next_state == B;
assign Y4 = next_state == D;
endmodule
I can't understand why this code can't solve the problem. Using this code, Y2 and Y4 are stuck at GND. I think there's a problem with "casez", but I am not sure.
Could you give me a correct answer and tell me the reason?
There are two major bugs in your code. When I run the simulation of your code on HDLBits, I see many warning messages which directly point to the problems, specifically, the ones under the heading: "Warning messages that may be important".
The 1st problem is that the state parameter values are decimal format, not binary format. You need to add the 6'b prefix to all the values:
parameter A = 6'b000001, B = 6'b000010, C = 6'b000100, D = 6'b001000,
E = 6'b010000, F = 6'b100000;
The 2nd problem is the width of the next_state signal. It is only 3 bits wide, but it must be 6 bits wide in order to assign a 6-bit value to it. Use:
reg [5:0] next_state;
These changes fix the problem mentioned in the question: Y2 and Y4 are no longer stuck at GND. The changes also eliminate all warning messages.
Going forward, you really need to create your own testbench to debug further problems. Unfortunately, the HDLBits online interface to the exercises like the one in the question does not allow you to see waveforms of internal signals.

one hot encoding in Verilog

Im just starting to learn how to code in Verilog. Can anyone help me figure out how to implement the following code in verilog using one-hot encoding
module Controller(b, x, clk, rst);
input b, clk, rst;
output x;
reg x;
parameter Off = 2'b00,
On1 = 2'b01,
On2 = 2'b10,
On3 = 2'b11;
reg [1:0] currentstate;
reg [1:0] nextstate;
//state register
always # (posedge rst or posedge clk)
begin
if(rst==1)
currentstate <= Off;
else
currentstate <= nextstate;
end
//combinational
always # (*)
begin
case (currentstate)
Off: begin
x <= 0;
if(b==0)
nextstate <= Off;
else
nextstate <= On1;
end
On1 : begin
x <= 1;
nextstate <= On2;
end
On2 : begin
x <= 1;
nextstate <= On3;
end
On3 : begin
x <= 1;
nextstate <= Off;
end
endcase
end
I tried changing the parameters to:
parameter Off = 4'b0001,
On1 = 4'b0010,
On2 = 4'b0100,
On3 = 4'b1000;
However, ive read that this is not a good implementations.
Some of the advantages of onehot encoding in FSMs are as follows:
Low switching activity. Since only single bit is switched at a time, the power consumption is less and it is less prone to glitches.
Simplified encoding. One can determine the state just by looking at the bit position of '1' in the current state variable.
The disadvantage of this technique is that it requires more number of flops. So, if one has a FSM with 10 different states, one needs 10 flops, while one needs only 4 flops when using decimal encoding.
Coming to your question, it is simple to change to onehot encoded FSM. One needs to implement a case statement based on the position of 1 in the currentstate variable. The code snippet can be implemented as follows:
parameter Off = 2'b00,
On1 = 2'b01,
On2 = 2'b10,
On3 = 2'b11;
//...
always # (*)
begin
nextstate = 4'b0000;
case (1'b1)
currentstate[Off] : begin
x = 0;
if(b==0)
nextstate[Off] = 1'b1;
else
nextstate[On1] = 1'b1;
end
currentstate[On1] : begin
x = 1;
nextstate[On2] = 1'b1;
end
//...
A simple example is available at this link and explanation is over here. Cummings paper is also a good source for more info.
EDIT: As #Greg pointed out, it was a copy-paste error. A combinational block must use blocking assignments.

verilog syntax error near always

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

Implementing one-bit flags in a 32Bit ALU using Verilog

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.

Can't get my head around testbenches

I am having trouble making testbenches. It is far into the quarter in my school but I feel like I am missing out on some fundamentals.
Here I am trying to make a 2 by 4 decoder, but I want to simulate it inside verilog.
module decoder2to4(x, enable, y);
input [1:0] x; //this is my decoder input
input enable;
output [3:0] y;
reg [3:0] y;
always #(x, enable ) //
begin
if(enable==0) //if enable isn't on, all outputs WON'T OUTPUT correct and give us 1111
y = 4'b1111;
else //if enable is high...
if (x == 2'b00) //...then we check our inputs and give corresponding outputs
y = 4'b0001;
if (x == 2'b01)
y = 4'b0010;
if (x == 2'b10)
y = 4'b0100;
if (x == 2'b11);
y = 4'b1000;
end
endmodule
This is my simulation file ~ did i write it correctly ?
module testbench_2to4decoder;
reg [1:0] x; //use reg not wire to assign values
wire [3:0] y; //for the outputs
2to4Decoder uut(x,y);
initial begin
x = 2'b00;
enable = 1'b0; //keep it off
#10 //wait some time
enable = 1'b1; //turn enable on
#10; //wait some time
x = 2'b01; //input 01
#10; //wait some time
x = 2'b10; //input 10
#10; //then
x = 2'b11; //input 11
#10;
enable = 1'b0; //turn it off
#10;
end
endmodule
You are not instantiating the design properly. Firstly, enable is not connected. enable is not even declared in testbench.
Also, the module name is wrong. Instead of following:
2to4Decoder uut(x,y);
You must have:
decoder2to4 uut(x,enable, y);
Using a reset logic is encouraged to have default values of output. But since this is a combinational circuit, it is not mandatory here.
The inputs can be provided by using a for or repeat loop and increment variable x in it. But this is just for coding efficiency.
Rest of the things seems to be fine. Refer Module instantiation link.

Resources