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
Related
I'm an economics student slowly switching from MATLAB to Julia.
Currently, my problem is that I don't know how to declare (preallocate) a vector that could store interpolations.
Specifically, when I execute something close to:
function MyFunction(i)
# x, y vectors are some functions of 'i' defined here
f = LinearInterpolation(x,y,extrapolation_bc=Line())
return f
end
g = Vector{Function}(undef, N)
for i = 1:N
g[i] = MyFunction(i)
end
I get:
ERROR: LoadError: MethodError: Cannot `convert` an object of type Interpolations.Extrapolation{Float64,1,Interpolations.GriddedInterpolation{Float64,1,Float64,Gridded{Linear},Tuple{Array{Float64,1}}},Gridded{Linear},Line{Nothing}} to an object of type Function
If I, instead of g=Vector{Function}(undef, N), declare g=zeros(N), I get a similar error message (ending with with ...Float64 rather than with ... Function).
When I, instead, declare:
g = Interpolations.Extrapolation{Float64,1,Interpolations.GriddedInterpolation{Float64,1,Float64,Gridded{Linear},Tuple{Array{Float64,1}}},Gridded{Linear},Line{Nothing}}(N)
I get:
LoadError: MethodError: no method matching Interpolations.Extrapolation{Float64,1,Interpolations.GriddedInterpolation{Float64,1,Float64,Gridded{Linear},Tuple{Array{Float64,1}}},Gridded{Linear},Line{Nothing}}(::Int64) Closest candidates are: Interpolations.Extrapolation{Float64,1,Interpolations.GriddedInterpolation{Float64,1,Float64,Gridded{Linear},Tuple{Array{Float64,1}}},Gridded{Linear},Line{Nothing}}(::Any, !Matched::Any) where {T, N, ITPT, IT, ET}
When I don't declare "g" at all, then I get:
ERROR: LoadError: UndefVarError: g not defined
Finally, when I declare:
g = Vector{Any}(undef, N)
the code works, though I'm afraid this might induce some type-change of a variable g, thereby slowing down my performance-sensitive code.
How, ideally then, should I declare g in this case?
EDIT:
In reality, my problem is a bit more complex, more like the following:
function MyFunction(i)
# x, y vectors are some functions of 'i' defined here
f = LinearInterpolation(x,y,extrapolation_bc=Line())
h = is a T-vector of some functions of x,y
A = is some matrix depending on x,y
return h, A, f
end
h = Matrix{Function}(undef, T, N)
A = zeros(T,I,N)
g = Vector{Any}(undef, N)
for i = 1:N
h[:,i], A[:,:,i], g[i] = MyFunction(i)
end
So, when I use either comprehension or broadcasting (like h, A, g = [MyFunction(i) for i in 1:N] or h, A, g = MyFunction.(1:N)), as users Benoit and DNS suggested below, the outputs of my function are 3 tuples, h, A, g, each containing {h[i], A[i], g[i]} for i=1,2,3. If I use only 1 output variable on the LHS, instead, i.e.: MyOutput = [MyFunction(i) for i in 1:N] or MyOutput[i] = MyFunction.(1:N), then MyOutput becomes a vector with N tuple entries, every tuple consisting of {h[i], A[i], g[i]} i=1,2,3,...,N. I bet there's a way of extracting these elements from the tuples in MyOutput and filling them inside h[:,i], A[:,:,i], g[i], but that seems a bit cumbersome and slow.
You could do
f = MyFunction(1)
g = Vector{typeof(f)}(undef, N)
g[1] = f
for i = 2:N
g[i] = MyFunction(i)
end
I think also map should figure out the type:
map(MyFunction, 1:N)
A simple solution is to use a comprehension:
g = [MyFunction(i) for i in 1:N]
or elegantly use the dot syntax:
g = MyFunction.(1:N)
(Credit to DNF for the dot-syntax solution suggested in the comments.)
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);
Suppose in a program, I write this function for dividing 2 values:
function [63:0] DIV_VAL; // Function for Multiplying two values 32 bits.
input [63:0] a, b;
always # (a or b)
DIV_VAL = a / b;
endfunction
Then later in the code I want to call this function with input Znk1 BUT rotating them 16 bits and 12 bits (first and second argument of the function). Moreover, since the function DIV_VAL answer me with a number of 64 bits, I only want to 32 bits from it, to be loaded to NC_1: Like this.
NC_1 = DIV_VAL [31:0] (Znk1 << 16, Znk1 >> 12) ;
Is this allowed, does it work? I'm not sure about the order also.
Second question: As alternative for this situation, a friend told me I can define some registers like a, b and use them to do something like this:
a = Znk1 << 16;
b = Znk1 >> 12;
NC_1 = DIV_VAL [31:0] (a, b);
NC_1 = NC_1[31:0];
You can't put an always block inside a function. Your function should be:
function [63:0] DIV_VAL; // Function for Multiplying two values 32 bits.
input [63:0] a, b;
DIV_VAL = a / b;
endfunction
or as you've written using an old-fashioned style, perhaps:
function [63:0] DIV_VAL (input [63:0] a, b); // Function for Multiplying two values 32 bits.
DIV_VAL = a / b;
endfunction
You can then call the function with expressions in the function call, if you wish:
NC_1 = DIV_VAL (Znk1 << 16, Znk1 >> 12) ;
but truncating the return value explicitly as you were doing is not allowed. But you don't need to truncate explicitly, Verilog will do it implicitly. (Hence no [31:0] in the above code.)
I want to compare the performance of two models using the F statistic. Here is a reproducible example and the expected results:
load carbig
tbl = table(Acceleration,Cylinders,Horsepower,MPG);
% Testing separetly both models
mdl1 = fitlm(tbl,'MPG~1+Acceleration+Cylinders+Horsepower');
mdl2 = fitlm(tbl,'MPG~1+Acceleration');
% Comparing both models using the F-test and p-value
numerator = (mdl2.SSE-mdl1.SSE)/(mdl1.NumCoefficients-mdl2.NumCoefficients);
denominator = mdl1.SSE/mdl1.DFE;
F = numerator/denominator;
p = 1-fcdf(F,mdl1.NumCoefficients-mdl2.NumCoefficients,mdl1.DFE);
We end up with F = 298.75 and p = 0, indicating mdl1 is significantly better than mdl2, as assessed by the F statistic.
Is there anyway to obtain the F and p values without performing twice fitlm and doing all the computation?
I tried to run a coefTest, as suggested by #Glen_b, however the function is poorly documented and the results are not the ones I'm expecting.
[p,F] = coefTest(mdl1); % p = 0, F = 262.508 (this F test mdl1 vs constant mdl)
[p,F] = coefTest(mdl1,[0,0,1,1]); % p = 0, F = 57.662 (not sure what this is testing)
[p,F] = coefTest(mdl1,[1,1,0,0]); % p = 0, F = 486.810 (idem)
I believe I should carry the test with a different null hypothesis (C) using the function [p,F] = coeffTest(mdl1,H,C). But I don't really know how to do it and there's no example.
This answer is in regards to comparing two linear regression models where one model is a restricted version of the other.
Short answer:
To do an F-test on the restriction that the 3rd and 4th elements of your estimated, coefficient vector b are zero:
[p, F] = coefTest(mdl1, [0, 0, 1, 0; 0, 0, 0, 1]);
Further explanation:
Let b be our estimated vector. Linear restrictions on b are typically written in a matrix form: R*b = r. The restriction that 3rd and 4th element of b are zero would be written:
[0, 0, 1, 0 * b = [0
0, 0, 0, 1] 0];
The matrix [0, 0, 1, 0; 0, 0, 0, 1] is what coefTest calls the H matrix in the docs.
P = coefTest(M,H), with H a numeric matrix having one column for each
coefficient, performs an F test that H*B=0, where B represents the
coefficient vector.
Long version
Sometimes with this econometric routines, it's nice just to write it out yourself so you know what's really going on.
Remove rows with NaN because they just add unrelated complexity:
tbl_dirty = table(Acceleration,Cylinders,Horsepower,MPG);
tbl = tbl_dirty(~any(ismissing(tbl_dirty),2),:);
Do the estimation etc...
n = height(tbl); % number of observations
y = tbl.MPG;
X = [ones(n, 1), tbl.Acceleration, tbl.Cylinders, tbl.Horsepower];
k = size(X,2); % number of variables (including constant)
b = X \ y; % estimate b with least squares
u = y - X * b; % calculates residuals
s2 = u' * u / (n - k); % estimate variance of error term (assuming homoskedasticity, independent observations)
BCOV = inv(X'*X) * s2; % get covariance matrix of b assuming homoskedasticity of error term etc...
bse = diag(BCOV).^.5; % standard errors
R = [0, 0, 1, 0;
0, 0, 0, 1];
r = [0; 0]; % Testing restriction: R * b = r
num_restrictions = size(R, 1);
F = (R*b - r)'*inv(R * BCOV * R')*(R*b - r) / num_restrictions; % F-stat (see Hiyashi for reference)
Fp = 1 - fcdf(F, num_restrictions, n - k); % F p-val
For reference, can look at p. 65 of Hiyashi's book Econometrics.
No, there is not.
Fitlm fits an arbitrary model. In your case a regression model with an intercept and either one or three regressors. It might seem that the model with three regressors can use information from the model with one regressor, but this is only true if there are some restrictions on the model and even then this overlapping information is limited.
Fitlm is a very general framework which can be used for arbitrary models. Doing multiple regressions at the same time with sharing of information can thus get quite complex and is not implemented.
It is possible to implement this yourself for these two specific models. Usually such a linear regression is solved using the covariance matrix:
Beta = (X' X) ^-1 X' y
were X is the data with the variables as columns and y is the target variable. In this case you could reuse part of the covariance matrix for which you only need the columns from the smaller regression: the variation in Acceleration. Since adding 2 new variables adds 8 values yo the covariance matrix you only save 1/9 of the time. Furthermore, the heaviest part is the inversion. Thus the time improvement is very very little.
In short, just do two separate regressions
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