I'm trying to solve this problem from altera Lab.
Here's my code :
module AlteraLAB2
(
input [17:0] SW,
output [17:0] LEDR,
output [7:0] LEDG
);
wire S;
wire [7:0] X,Y,M;
//Use switch SW17 on the DE2 board as the s input, switches SW7−0 as the X input and SW15−8 as the Y input
assign S = SW[17];
assign X = SW[7:0];
assign Y = SW[15:8];
//Connect the SW switches to the red lights LEDR and connect the output M to the green lights LEDG7−0
assign LEDR = SW[17:0];
assign LEDG = M;
//The multiplexer can be described by the following Verilog statement: assign m=(~s & x)|(s & y);
assign M[0] = (~S & X[0]) | (S & Y[0]);
assign M[1] = (~S & X[1]) | (S & Y[1]);
assign M[2] = (~S & X[2]) | (S & Y[2]);
assign M[3] = (~S & X[3]) | (S & Y[3]);
assign M[4] = (~S & X[4]) | (S & Y[4]);
assign M[5] = (~S & X[5]) | (S & Y[5]);
assign M[6] = (~S & X[6]) | (S & Y[6]);
assign M[7] = (~S & X[7]) | (S & Y[7]);
endmodule
I solved it assigning step by step the values in M, but I don't understand why this does not work:
M=(~S & X) | (S & Y);
Could someone explain why?
Note the bit widths of the signals in the expression
M=(~S & X) | (S & Y);
S is only one bit while X is 8 bits. The bitwise AND of the two will result in a one-bit result, which is not what you want.
It's common in Verilog to use a ternary expression in situations like this. For example,
assign M = S ? Y : X;
It does not work because S is a 1-bit signal and Y is an 8-bit signal. When you bitwise AND a 1-bit signal with an 8-bit signal, the 1-bit signal (S) is left extended with 0's.
For example, if S=1 and Y='hff, (S & Y) = (8'b0000_0001 & 8'b1111_1111) = 8'b0000_0001.
The same goes for (~S & X).
Using the replicated concatenation operator will work:
assign M = (~{8{S}} & X) | ({8{S}} & Y);
It is more conventional in Verilog to use the ternary operator to describe a mux:
assign M = (S) ? Y : X;
Related
I was trying to write Verilog code of a two bit comparator, but I keep getting errors. Any help?
Error Codes:
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(5) near text: ";"; expecting ")"
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(7) near text: ";"; expecting ")"
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(15) near text: "~"; expecting ")"
Design:
module twobit_comparator(
//assigning inputs
input wire [1:0] A, B;
// assigning outputs
output wire LT, GT, EQ;
// L=Less, G=Greater, E=Equal
);
wire [9:0] s;
//A = B output
assign s0 = (~A[1] & ~A[0] & ~B[1] ~B[0]);
assign s1 = (~A[1] & A[0] & ~B[1] & B[0]);
assign s2 = (A[1] & ~A[0] & B[1] & ~B[0]);
assign s3 = (A[1] & A[0] & b[1] & B[0]);
assign EQ = s0 | s1 | s2 | s3;
//A less than B output
assign s4 = (~A[0]) & (~A[1]) & B[0];
assign s5 = (~A[1]) & B[1];
assign s6 = (~A[0]) & B[1] & B[0];
assign LT = s4 | s5| s6;
// A greater than B output
assign s7 = (~B[0]) & (~B[1]) & A[0];
assign s8 = (~B[1]) & A[1];
assign s9 = (~B[0]) & A[1] & A[0];
assign GT = s7 | s8 | s9;
endmodule
Separate ports with commas, not semicolons, and do not end the port list with a semicolon:
module twobit_comparator(
//assigning inputs
input wire [1:0] A, B,
// assigning outputs
output wire LT, GT, EQ
// L=Less, G=Greater, E=Equal
);
You are missing the & operator; I added it here:
assign s0 = (~A[1] & ~A[0] & ~B[1] & ~B[0]);
// ^
I changed b to B here (Verilog is case-sensitive):
assign s3 = (A[1] & A[0] & B[1] & B[0]);
// ^
I don't get any more compile errors with the changes above. However, you declared signal s, but it is not used. And, you did not declare s0, s1, etc., but you are using them. This works because Verilog allows you to use undeclared wires when they are 1-bit wide. But, you should declare all signals. For example, you could use:
wire [9:0] s;
assign s[0] = (~A[1] & ~A[0] & ~B[1] & ~B[0]);
assign s[1] = (~A[1] & A[0] & ~B[1] & B[0]);
I'm got a error when running Implementation at vivado 2018.2
this is error detail Info:
[Place 30-494] The design is empty
Resolution: Check if opt_design has removed all the leaf cells of your design. Check whether you have instantiated and connected all of the top level ports.
[Common 17-69] Command failed: Placer could not place all instances
and my codes is following:
`timescale 1ns/1ns
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output reg sum, cout;
reg t1, t2, t3;
always
#(a or b or cin) begin
sum <= (a ^ b & cin);
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
endmodule
module fa_top;
reg pa, pb, pci;
wire pco, psum;
fa_seq uf1(pa, pb, pci, psum, pco);
initial
begin: blk_only_once
reg[3:0] pal;
for(pal = 0; pal < 8; pal = pal + 1)
begin
{pa,pb,pci} <= pal;
#5 $display("pa,pb,pci = %b%b%b",pa,pb,pci,":::pco,psum=%b%b",pco,psum);
end
end
endmodule
thanks for your answer.
Check whether you have instantiated and connected all of the top level ports.
It looks like you synthesized your actual design AND your test-bench.
The test-bench is the top level module and has no ports so all logic is optimised away.
You should split your design in files which hold the RTL and files which hold the test-bench/simulation code. In Vivado you have to specify what type it is if you 'add a file' here is a screen shot:
Your code has a latch inferred. Moreover you have used both blocking and non-blocking assignment in the same always block.
always
#(a or b or cin) begin //Not all dependencies are mentioned
sum <= (a ^ b & cin); //Non-blocking assignment
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
I suggest you to re-write the always block as shown below.
always
#(*) begin
sum = (a ^ b & cin);
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
Actually you don't need an always block for the above combinational logic. Simply use assign statements.
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output sum, cout;
wire t1, t2, t3;
assign sum = (a ^ b & cin);
assign t1 = a & cin;
assign t2 = b & cin;
assign t3 = a & b;
assign cout = (t1 | t2) | t3;
endmodule
However an efficient way of writing a full adder code would be :-
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output sum, cout;
assign {cout,sum} = (a + b + cin);
endmodule
I'm new to Verilog. Here's what I have done so far and the 4-bit CLA works. However, the 16-bit (using instances of 4-bit CLA) doesn't. The problem is definitely in setting the Cout_itermed (intermediate carries) values from block propagate (BP) and block generate (BG). I've created a module carries to deal with this.
In Xilinx ISE, the output waveform shows up as this (no wave shown):
module CLA_4bit(
output [3:0] S,
output Cout, PG, GG,
input [3:0] A, B,
input Cin
);
wire [3:0] G,P,C;
assign G = A & B; //Generate
assign P = A ^ B; //Propagate
assign C[0] = Cin;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);
assign Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
assign S = P ^ C;
assign PG = P[3] & P[2] & P[1] & P[0]; // block generate
assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]); // block propagate
endmodule
module CLA_16bit(
output reg [15:0] S,
output reg Cout,
input [15:0] A, B,
input Cin
);
reg [3:0] BP, BG;
reg [3:0] Cout_itermed;
carries my_carries(BP, GP, Cin, Cout_itermed, Cout);
CLA_4bit cla0(S[3:0], Cout_itermed[0], BP[0], BG[0], A[3:0], B[3:0], Cin);
CLA_4bit cla1(S[7:4], Cout_itermed[1], BP[1], BG[1], A[7:4], B[7:4], Cout_itermed[0]);
CLA_4bit cla2(S[11:8], Cout_itermed[2], BP[2], BG[2], A[11:8], B[11:8], Cout_itermed[1]);
CLA_4bit cla3(S[15:12], Cout_itermed[3], BP[3], BG[3], A[15:12], B[15:12], Cout_itermed[2]);
Cout = Cout_itermed[3];
endmodule
module carries (
input [3:0] BP,
input [3:0] BG,
input Cin,
output reg [3:0] Cout_itermed,
output reg Cout
);
assign Cout_itermed[0] = BG[0] | (BP[0] & Cin);
assign Cout_itermed[1] = BG[1] | (BP[1] & Cout_itermed[0]);
assign Cout_itermed[2] = BG[2] | (BP[2] & Cout_itermed[1]);
assign Cout = Cout_itermed[3];
endmodule
The waveform does show up (and correctly) when I run a test bench of the 4 bit CLA. Could anyone explain where the problem lies in the carries or the CLA_16bit module?
Cout_itermed has two drivers - the first being the Cout outputs of a CLA_4bit, and the second being the Cout_itermed output of the carries module.
The same applies to Cout in CLA_16bit (though it's two drivers end up being the same signal, Cout_itermed[3], in CLA_16bit and carries).
Remember that in Verilog you're describing physical circuitry, and you should never have two sources (drivers) connected to the same wire - that's how we get short circuits!
The following is based on https://en.wikipedia.org/wiki/Lookahead_carry_unit#16-bit_adder.
What you'll want to do is define remove the Cout_itermed[x] from the Cout port in the CLA_16bits (you can just leave the port hanging). You should move the logic to determine Cout_itermed[3] (i.e. BG[3] | (BP[3]&Cout_itermed[2])) to the carries module.
I'm having a lot of trouble making any sort of sense of this problem. I'm supposed to create a module for an 8 bit wide 2-to-1 multiplexer using Verilog.
The question:
Write a verilog module that uses 8 assignment statements to describe the circuit. Use SW[17] on the DE2 board as the s input, switches [7:0] as the X input, switches [15:8] as the Y input. Connect SW switches to the red lights LEDR and output M to the green light LEDG [7:0].
My code:
module example(M, X, Y, S)
input[15:0] SW;
input SW[17];
output [7:0] LEDR;
output [7:0] LEDG;
output [7:0] M;
wire [7:0] X = SW[7:0];
wire [7:0] Y = SW[15:8];
wire S = SW[17]
assign M[0] = X[0] & ~S | Y[8] & S;
assign M[1] = X[1] & ~S | Y[9] & S;
assign M[2] = X[2] & ~S | Y[10] & S;
assign M[3] = X[3] & ~S | Y[11] & S;
assign M[4] = X[4] & ~S | Y[12] & S;
assign M[5] = X[5] & ~S | Y[13] & S;
assign M[6] = X[6] & ~S | Y[14] & S;
assign M[7] = X[7] & ~S | Y[15] & S;
endmodule
I don't understand how I'm supposed to assign m to the green LEDG[7:0] since I've already assigned each M to those conditional statements. Anyone know how to get around this?
While there are multiple ways to do this, I suggest make a wrapper module containing the board i/o as inputs and outputs and instantiate your MUX inside of it:
module top(input [17:0] SW,
output [15:0] LEDR,
output [7:0] LEDG);
example ex(.M(LEDG), .s(SW[17]), .X(SW[7:0]), .Y(SW[15:8]));
assign LEDR[7:0] = X;
assign LEDR[15:8] = Y;
endmodule
[insert your mux module minus the board i/o here]
If you cannot use the above solution, you can look up how to use the Pin Planner in QuartusII (which I assume you are using from the DE2 reference in your prompt).
I have just learned about the CLA adder am a little confused about getting the sum. I see there are two versions of p, p = a or b and p = a xor b.
If I simulate this code it will give the correct result:
module CLA_4bit(
output [3:0] S,
output Cout,
input [3:0] A,B,
input Cin
);
wire [3:0] G,P,C;
assign G = A & B;
assign P = A ^ B;
assign C[0] = Cin;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);
assign Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
assign S = P ^ C;
endmodule
However, if I change P = A ^ B to P = A | B it would give an incorrect sum. What changes to the code would be needed to have it work with P = A | B ?
The formula for S (P^C) is valid for P computed with XOR operation. As you probably know, the only difference in the truth tables between OR and XOR operation is when both bits are 1. That's why the formula for Sshould be slightly different if you use OR operation:
S = (P & (~G)) ^ C