2 bit signed Multiplier - binary

Design a 2-bit signed multiplier using one instantiation of your 4-bit adder. Remember that you need to sign extend your two 2-bit inputs to a full 4-bits.
This was my assignment and I came up with following code but some of my outputs are wrong. Can anyone tell me what I am doing wrong?
module mult(C,A,B);
output signed[3:0]C;
input signed[1:0]A,B;
reg signed[3:0]sA,sB;
assign sA = {A[1],A[1],A};
assign sB = {B[1],B[1],B};
wire carry;
wire signed[3:0] A1;
wire signed[3:0] A2;
wire signed[3:0] sum0;
and(A1[0],sA[0],sB[0]);
and(A1[1],sA[1],sB[0]);
and(A1[2],sA[2],sB[0]);
and(A1[3],sA[3],sB[0]);
assign A2[0] = 0;
and(A2[1],sA[0],sB[1]);
and(A2[2],sA[1],sB[1]);
and(A2[3],sA[2],sB[1]);
adder4bit a1(.A(A1),.B(A2),.Co(carry),.sum(sum0));
assign C[0] = sum0[0];
assign C[1] = sum0[1];
assign C[2] = sum0[2];
assign C[3] = sum0[3];
endmodule
module adder4bit(A,B,sum,Co);
input signed[3:0]A,B;
output signed [4:0]sum;
reg signed[4:0]a,b;
output Co;
wire Ci;
assign Ci = 1'b0;
assign a = {A[3],A};
assign b = {B[3],B};
FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w1));
FA a1(.A(a[1]),.B(b[1]),.Ci(w1),.sum(sum[1]),.Co(w2));
FA a2(.A(a[2]),.B(b[2]),.Ci(w2),.sum(sum[2]),.Co(w3));
FA a3(.A(a[3]),.B(b[3]),.Ci(w3),.sum(sum[3]),.Co(w4));
FA a4(.A(a[4]),.B(b[4]),.Ci(w4),.sum(sum[4]),.Co(Co));
endmodule
module FA(A,B,Ci,Co,sum);
input A,B,Ci;
output sum,Co;
assign sum = (A^B)^Ci;
assign Co = (B&Ci) | (A&Ci) | (A&B);
endmodule

There were some signals declared as reg connected to port outputs, reg must be assigned in procedural blocks.
I also made the carry bits in the adder an explicit wire vector, instead of multiple implicit wires. Implicit wires are dangerous a typo leads to a disconnection.
Also I declared the sum0 in the multiplier to have the same width as the output in of the sum port where it is connected, even though the bit 4 will not be used.
In terms of logic you made only one mistake, the A * B = A * B[0] - 2*A * B[1] instead of A * B[0] + 2*B[1] if B is a 2-bit signed integer. Because B[1] is the sign bit, thus B = B[0] - 2*B[1]. I fixed this by using the unary - directly in the port connection, I will leave it to you to write this structurally.
module mult(C,A,B);
output signed[3:0]C;
input signed[1:0]A,B;
wire signed[3:0]sA,sB;
assign sA = {A[1],A[1],A};
assign sB = {B[1],B[1],B};
wire carry;
wire signed[3:0] A1;
wire signed[3:0] A2;
wire signed[4:0] sum0;
and(A1[0],sA[0],sB[0]);
and(A1[1],sA[1],sB[0]);
and(A1[2],sA[2],sB[0]);
and(A1[3],sA[3],sB[0]);
assign A2[0] = 0;
and(A2[1],sA[0],sB[1]);
and(A2[2],sA[1],sB[1]);
and(A2[3],sA[2],sB[1]);
// FIXME: Notice that I am passing -A2, the simulator will
// negate the signal automatically. Maybe for your assignment
// you are requried to expand this using logic primitives...
adder4bit a1(.A(A1),.B(-A2),.Co(carry),.sum(sum0));
assign C[0] = sum0[0];
assign C[1] = sum0[1];
assign C[2] = sum0[2];
assign C[3] = sum0[3];
endmodule
module adder4bit(A,B,sum,Co);
input signed[3:0]A,B;
output signed [4:0]sum;
wire signed[4:0]a,b;
output Co;
wire [4:1] w;
wire Ci;
assign Ci = 1'b0;
assign a = {A[3],A};
assign b = {B[3],B};
FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w[1]));
FA a1(.A(a[1]),.B(b[1]),.Ci(w[1]),.sum(sum[1]),.Co(w[2]));
FA a2(.A(a[2]),.B(b[2]),.Ci(w[2]),.sum(sum[2]),.Co(w[3]));
FA a3(.A(a[3]),.B(b[3]),.Ci(w[3]),.sum(sum[3]),.Co(w[4]));
FA a4(.A(a[4]),.B(b[4]),.Ci(w[4]),.sum(sum[4]),.Co(Co));
endmodule
module FA(A,B,Ci,Co,sum);
input A,B,Ci;
output sum,Co;
assign sum = (A^B)^Ci;
assign Co = (B&Ci) | (A&Ci) | (A&B);
endmodule

Related

Why MATLAB Simulink says "imulink cannot propagate the variable-size mode from the output port ..."

I am trying to implement a Software in the loop simulation, I do not find the issue here. I am currently debugging using constant input vectors. Appears the problem is given by the allocation and definition of u1, the output variable.
What am I doing wrong?
The code works in a Function MATLAB evnironment, but the same does not work in simulink MATLAB Function Block.
function [u1,deltau] = Controller(Omega,Psi,Lzerot,xm,y,sp,m)
persistent Xf
if isempty(Xf)
Xf = [xm;(y-sp)];
end
persistent xm_old
if isempty(xm_old)
xm_old = xm;
end
persistent u
if isempty(u)
u = zeros(m,1);
end
persistent deltau_old
if isempty(deltau_old)
deltau_old = zeros(m,1);
end
% O P T I M I Z A T I O N
eta = -(Omega\Psi)*(Xf); % (L. Wang pg. 99/100)
deltau = Lzerot*eta; % Kmpc = L(0)'*(Omega\Psi) & Du = - Kmpc * x(k)
if deltau == deltau_old
else
u = u + deltau;
deltau_old = deltau;
end
u1 = u;
% U P D A T E
if xm == xm_old
% elseif y == y_old
% Xf = [xm-xm_old;(y-sp)];
else
Xf = [xm-xm_old;(y-sp)];
xm_old = xm;
end
end
Thank you for your help.
I tried to pre-allocate the u1 variable, as (m,1) vector but it does not affect the problem.
Cleaning the function and optimizing is part of the task I want to achieve. Is it just that I need the zero allocation of u, for that reason I am using the persistant type of variable.
I do not want my variable to change size. It has not to.
Even if I change to "variable size" type of output, it does not solve the problem.

Verilog Binary Coded Decimal Adder Not Outputting Correctly

I'm new to Verilog and basically trying to teach myself a Digital Logic Design module for university. I am trying to write a BCD Adder in Verilog using two Full Adders with some logic in between for conversion to BCD when needed.
Here is my code:
module binary_adder (
output [3:0] Sum,
output C_out,
input [3:0] A, B,
input C_in
);
assign {C_out, Sum} = A || B || C_in;
endmodule
module BCD_Adder (
output [3:0] Sum,
output Carry_out,
input [3:0] Addend, Augend,
input Carry_in
);
wire [3:0] Z, correction;
wire adder1C_out, carryInAdder2, adder2C_out;
binary_adder adder1 (.Sum(Z), .C_out(adder1C_out), .A(Addend), .B(Augend), .C_in(Carry_in));
assign Carry_out = (adder1C_out || (Z[3] && Z[1]) || (Z[3] && Z[2]));
assign correction = (Carry_out) ? (4'b0110) : (4'b0000);
assign carryInAdder2 = (1'b0);
binary_adder adder2 (.Sum(Sum), .C_out(adder2C_out), .A(correction), .B(Z), .C_in(carryInAdder2));
endmodule
For some reason, I keep getting the following outputs:
Submitted: A = 0000, B = 0010, Carry In = 0, Sum = 0001, Carry Out = 0
Expected: A = 0000, B = 0010, Carry In = 0, Sum = 0010, Carry Out = 0
Submitted: A = 0000, B = 0011, Carry In = 0, Sum = 0001, Carry Out = 0
Expected: A = 0000, B = 0011, Carry In = 0, Sum = 0011, Carry Out = 0
Submitted: A = 0000, B = 0100, Carry In = 0, Sum = 0001, Carry Out = 0
Expected: A = 0000, B = 0100, Carry In = 0, Sum = 0100, Carry Out = 0
It basically continues like this for all values. My A, B, Carry In and Carry Out values always match, but for some reason the output sum is always 0001. I'm not sure where I'm going wrong, the logic seems okay to me. I am very new to this and only know the basics, so any help would be greatly appreciated!
Thanks,
Wes
The logic in binary_adder does not implement addition; as it is currently written, it will just set Sum to 1 if any of A, B or C_in are non-zero.
While there are many architectures of multibit addition (see https://en.wikipedia.org/wiki/Adder_(electronics)#Adders_supporting_multiple_bits), the simplest to understand is the Ripple Carry Adder. It implements several full adders and chains them together to implement addition.
A simple implementation of this architecture looks like this:
module full_add(input A, B, Cin,
output S, Cout);
// Basic implementation of a Full Adder (see https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder)
assign S = A ^ B ^ Cin;
assign Cout = A & B | ((A ^ B) & Cin); // Note I use bit-wise operators like | and ^ instead of logical ones like ||; its important to know the difference
endmodule
module add(input [3:0] A, B,
input Cin,
output [3:0] S,
output Cout);
wire [3:0] Carries; // Internal wires for the carries between full adders in Ripple Carry
// This is an array instance which just makes [3:0], ie 4, instances of the full adder.
// Take note that a single Full Adder modules takes in single bits, but here
// I can pass bit vectors like A ([3:0]) directly which assign full_add[0].A = A[0], full_add[1].A = A[1], etc
// Common alternatives to using array instances (which are more rare) include generate statements or just instantiate the module X times
full_add f[3:0](.A(A), .B(B), .Cin({Carries[2:0], Cin}), .S(S), .Cout(Carries));
assign Cout = Carries[3];
endmodule

In octave, how to print a number up to d decimal places, where d is a value that the user inputs

I want to print a variable val up to d decimal places, where d is input by the user. The value of d is not known while writing the program.
I tried the following:
printf ('%.df',val);
printf ('%.{%i}f',d,val);
It doen't seem to work though.
You can use the special formatspecifier * to indicate a formatting argument. E.g.:
octave:1> val = exp(1)
val = 2.7183
octave:2> decimalPlaces = 3;
octave:3> fprintf('The value to 3 sig digits is: %.*f \n', decimalPlaces, val)
The value to 3 sig digits is: 2.718
The matlab documentation has a good section on this.
You'll need to generate the format string with the proper value first; it won't be replaced within fprintf:
d = 5;
val = 7.123456789
fmt_str = ['%.' num2str(d) 'f']; % fmt_str = '%.df', d replaced with number
fprintf(fmt_str, val);

XOR codin text Macro LibreOffice

I have an assignment to make a macro in LibreOffice that I have to code a text using XOR operations. the instructions are following.
izracunajHash function (password zacetni_hash) - This function will implement a hash function that will calculate the user's password from the initial seed for the pseudo-random number generator. To receive functions are set following additional requirements:
Variable zacetni_hash to the setpoint 17520
The function of taking the characters from the first character to the last
Walk through the characters need to implement the loop for
function encode (string) - output of the function will be encoded / decoded input string. Assume that the random number generator are set to the correct value. Encode only the characters whose ascii value is greater than 31. For admission functions are set following additional requirements:
The function of taking the characters from the last character to the first
Walk through the characters you must be implemented with the Do While Loop
sub kodiraj_besedilo (seed) - This subroutine ensures that encode all the paragraphs in plain text. Also in this subprogram the initialisation of the random value
kodiraj_UI sub - this subroutine contains a user interface for your macro is basically the main program. You will require a password for encryption and call routines sooner Headquarters
I have written to this point:
REM ***** BASIC *****
function izracunajHash(geslo, zacetni_hash)
zacetni_hash = 17520
hash = zacetni_hash
mask = &H00FFFFFF
dolzina = len(geslo)
If dolzina > 0 Then
for f=1 to dolzina step +1
podniz = mid(geslo,dolzina,1)
char = Asc("podniz")
hash = 33*hash + char
hash = hash AND mask
dolzina = dolzina +1
hash = hash AND &H00FFFFFF
next f
End If
izracunajHash = hash
End function
function kodiraj(niz)
y = 1
if Len(niz) > 0 Then
x = Len(niz)
Do While y > (x+1)
sign = Mid(niz, y, 1)
z1 = Asc(sign)
if z1 > 31 Then
z2 = (CInt(rnd()*31))
z1 = z1 XOR z2
z1 = Chr(z1)
Mid(niz,y,1,z1)
End If
y = y + 1
Loop
End If
kodiraj = niz
End function
Sub kodiraj_besedilo(seme)
Randomize(seme)
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
oPar.String = kodiraj(oPar.String)
End If
Loop
End Sub
Sub kodiraj_UI
geslo = InputBox("Vnesi niz:", "Geslo", "E1087385")
hash = izracunajHash(geslo, 17520)
kodiraj_besedilo(hash)
msgBox("KonĨaj")
End Sub

FFT implemetation in Verilog: Assigning Wire input to Register type array

I am trying to implement butterfly FFT algorithm in verilog.
I create K(Here 4) butterfly modules . I create modules like this.
localparam K = 4;
genvar i;
generate
for(i=0;i<N/2;i=i+1)
begin:BN
butterfly #(
.M_WDTH (3 + 2*1),
.X_WDTH (4)
)
bf (
.clk(clk),
.rst_n(rst_n),
.m_in(min),
.w(w[i]),
.xa(IN[i]),
.xb(IN[i+2]),
.x_nd(x_ndd),
.m_out(mout[i]),
.ya(OUT[i]),
.yb(OUT[i+2]),
.y_nd(y_nddd[i])
);
end
Each level I have to change input Xa and Xb for each Module (Here Number of level 3).
So I try to initialize reg type "IN"array and assign the array to input Xa and Xb. When I initialize "IN" array manually, it works perfectly.
The problem I face now, I couldn't assign Main module input X to register type "IN" array.
Main module input X ,
input wire signed [N*2*X_WDTH-1:0] X,
I have to assign this X into array "IN",
reg signed [2*X_WDTH-1:0] IN [0:N-1];
I assigned like this,
initial
begin
IN[0]= X[2*X_WDTH-1:0];
IN[1]=X[4*X_WDTH-1:2*X_WDTH];
IN[2]=X[6*X_WDTH-1:4*X_WDTH];
IN[3]= X[8*X_WDTH-1:6*X_WDTH];
IN[4]= X[10*X_WDTH-1:8*X_WDTH];
IN[5]=X[12*X_WDTH-1:10*X_WDTH];
IN[6]=X[14*X_WDTH-12*X_WDTH];
IN[7]= X[16*X_WDTH-1:14*X_WDTH];
end
I have gone through many tutorials and forums. No luck.
Can't we assign wire type to reg type array? If so how I can solve this problem.
Here is the Main module where I initialize Butterfly modules,
module Network
#(
// N
parameter N = 8,
// K.
parameter K = 3,
parameter M_WDTH=5,
parameter X_WDTH=4
)
(
input wire clk,
input wire rst_n,
// X
input wire signed [N*2*X_WDTH-1:0] X,
//Y
output wire signed [N*2*X_WDTH-1:0] Y,
output wire signed [K-1:0] y_ndd
);
wire y_nddd [K-1:0];
assign y_ndd ={y_nddd[1],y_nddd[0]};
reg [4:0] min=5'sb11111;
wire [4:0] mout [0:K-1];
reg x_ndd;
reg [2:0] count=3'b100;
reg [2*X_WDTH-1:0] w [K-1:0];
reg [2*X_WDTH-1:0] IN [0:N-1];
wire [2*X_WDTH-1:0] OUT [0:N-1];
assign Y = {OUT[3],OUT[2],OUT[1],OUT[0]};
reg [3:0] a;
initial
begin
//TODO : Here is the problem. Assigning Wire to reg array. Synthesize ok. In Simulate "red" output.
IN[0]= X[2*X_WDTH-1:0];
IN[1]=X[4*X_WDTH-1:2*X_WDTH];
IN[2]=X[6*X_WDTH-1:4*X_WDTH];
IN[3]= X[8*X_WDTH-1:6*X_WDTH];
IN[4]= X[10*X_WDTH-1:8*X_WDTH];
IN[5]=X[12*X_WDTH-1:10*X_WDTH];
IN[6]=X[14*X_WDTH-12*X_WDTH];
IN[7]= X[16*X_WDTH-1:14*X_WDTH];
//TODO :This is only a random values
w[0]=8'sb01000100;
w[1]=8'sb01000100;
w[2]=8'sb01000100;
w[3]=8'sb01000100;
end
/* levels */
genvar i;
generate
for(i=0;i<N/2;i=i+1)
begin:BN
butterfly #(
.M_WDTH (3 + 2*1),
.X_WDTH (4)
)
bf (
.clk(clk),
.rst_n(rst_n),
.m_in(min),
.w(w[i]),
.xa(IN[i]),
.xb(IN[i+N/2]),
.x_nd(x_ndd),
.m_out(mout[i]),
.ya(OUT[2*i]),
.yb(OUT[2*i+1]),
.y_nd(y_nddd[i])
);
end
endgenerate
always # (posedge clk)
begin
if (count==3'b100)
begin
count=3'b001;
x_ndd=1;
end
else
begin
count=count+1;
x_ndd=0;
end
end
always# (posedge y_ndd[0])
begin
//TODO
//Here I have to swap OUT-->IN
end
endmodule
Any help is appreciated.
Thanks in advance.
"Output is red", this likely means it is x this could be due to multiple drivers or an uninitialized value. If it was un-driven it would be z.
The main Issue I believe is that you do this :
initial begin
IN[0] = X[2*X_WDTH-1:0];
IN[1] = X[4*X_WDTH-1:2*X_WDTH];
...
The important part is the initial This is only evaluated once, at time 0. Generally everything is x at time zero. To make this an equivalent of the assign IN[0] = ... for a wire use always #* begin this is a combinatorial block which will update the values for IN when ever X changes.
always #* begin
IN[0] = X[2*X_WDTH-1:0];
IN[1] = X[4*X_WDTH-1:2*X_WDTH];
...
I am not sure why you do not just connect your X to your butterfly .xa and .xb ports directly though?
Other pointers
X is a bad variable name verilog as a wire or reg can hold four values 1,0,x or z.
In always #(posedge clk) you should be using non-blocking (<=) assignments to correctly model the behaviour of a flip-flop.
y_ndd is k bits wide but only the first 2 bits are assigned.
output signed [K-1:0] y_ndd
assign y_ndd = {y_nddd[1],y_nddd[0]};
Assignments should be in terms of their parameter width/size. For example IN has N entries but currently exactly 8 entries are assigned. There will been an issue when N!=8. Look into Indexing vectors and arrays with +:. Example:
integer idx;
always #* begin
for (idx=0; idx<N; idx=idx+1)
IN[idx] = X[ idx*2*X_WDTH +: 2*X_WDTH];
end
genvar gidx;
generate
for(gidx=0; gidx<N; gidx=gidx+1) begin
assign Y[ gidx*2*X_WDTH +: 2*X_WDTH] = OUT[gidx];
end
endgenerate