why does my Verilog adder-subtractor fail the addition here with 1 more than correct answer? - binary

I wrote a 4-bit full-adder-subtractor, and my code managed to operate subtraction but failed operating addition with 1 more than the correct answer: 0101+0101=1011. Help!
Here's the full-adder-subtractor code:
module Add_sub(x,y,co,u,en);
input [3:0] x, y;
input en; // en=1: add; en=0:sub
output [3:0] u;
output co;
wire [3:1]carry;
FA M0(x[0], y[0], en, en, u[0], carry[1]);
FA M1(x[1], y[1], carry[1], en, u[1], carry[2]);
FA M2(x[2], y[2], carry[2], en, u[2], carry[3]);
FA M3(x[3], y[3], carry[3], en, u[3], co);
endmodule
module FA(x,y,cin,en,u,co);
input x, y, cin, en;
output u, co;
wire b = !x^en;
assign u = x^y^cin;
assign co = (b&y)|(b&cin)|(y&cin);
endmodule
Here's the testbench code:
`timescale 1ns/1ns
module testbench();
reg [3:0]x, y;
reg en;
wire[3:0]u;
wire co;
Add_sub tb(.x(x), .y(y), .co(co), .u(u), .en (en));
initial begin
$monitor ($time, "x=%b, y=%b, co=%b, u=%b, en=%b",x,y,co,u,en);
end
initial begin
#0 x=5; y=5; en=1; // add operation
#20 x=5; y=5; en=0; // sub operation
#20 x=8; y=1; en=1; // add operation
#20 x=8; y=1; en=0; // sub operation
#20 $stop;
end
endmodule
Here's the simulation Wave:

I re-wrote your code as following:
module Add_sub(x,y,co,u,en);
input [3:0] x, y;
input en; // en=1: add; en=0:sub
output [3:0] u;
output co;
wire [3:1]carry;
wire ci = ~en;
FA M0(x[0], y[0], ci, en, u[0], carry[1]);
FA M1(x[1], y[1], carry[1], en, u[1], carry[2]);
FA M2(x[2], y[2], carry[2], en, u[2], carry[3]);
FA M3(x[3], y[3], carry[3], en, u[3], co);
endmodule
module FA(x,y,cin,en,u,co);
input x, y, cin, en;
output u, co;
wire b = en ? y : (~y);
assign u = x^b^cin;
assign co = (b&x)|(b&cin)|(x&cin);
endmodule

Related

Julia: how to optimally declare a vector containing interpolations?

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.)

2 bit signed Multiplier

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

Bug in the translation of a C file to a Cython file

I've succeeded in converting a C file in cython. But the two codes are giving me different results and I really cannot find where the bug is.
The relevant C code of my script is the following:
double empirical_measure(int N, double K, double d, double T, double dt, FILE *store){
/*Define variables*/
int kt;
int kt_max = (int) ((double)T/(double)dt);
double *xt;
xt=(double *)malloc(N*sizeof(double));
double bruit;
double S=0.0;
double xtmp;
double xtilde;
double x_diff;
double xi;
int i;
int j;
int l;
/*initial condition*/
for(i=0; i<N; i++){
xt [i]=rand()/((double) RAND_MAX)*2*M_PI;
}
/*Compute trajectories and empirical measure*/
for(kt=0; kt<kt_max; kt++){
for(i=0; i<N; i++){
S = 0.0;
xi = xt[i];
for(j=0; j<N; j++){
x_diff = xt[j] - xi;
S = S + sin(x_diff);
}
bruit= d*sqrt(dt)*gaussian();
xtilde = xi + ((K/N)*S)*dt + bruit;
xt[i] = fmod(xtilde, 2.0*M_PI);
}
}
return 0;
}
The gaussian function is a function which gives a random number from a Normal(0,1) distribution.
I translated into this cython code (where the output is a matrix with all the computations of xt[:,k] for all k, and not, for each k, a vector as in the C code):
def simul(int N, double K, double d, double T, double dt):
cdef int kt_max = int(T/dt)
cdef double S1
cdef double xtilde, x_diff, xtmp
cdef double[:] bruit = d*sqrt(dt)*np.random.standard_normal(N) #bruit generator
cdef double[:, ::1] xt = np.zeros((N, kt_max), dtype=np.float64)
cdef int kt, i, j, k
#initial conditions
X=np.random.uniform(0,2*np.pi,N)
for i in range(N):
xt[i,0]=X[i]
#Compute trajectories and empirical measure
for kt in range(kt_max-1):
for i in range(N):
S1 = 0.0
for j in range(N):
x_diff = xt[j,kt] - xt[i,kt]
S1 = S1 + sin(x_diff)
xtilde = xt[i,kt] + ((K/N)*S1)*dt + bruit[i]
xt[i,kt+1] = xtilde%(2*np.pi)
return xt
The problem is that if I run the two scripts with the same values I have really different results. For example, given:
N=600
K=5
T=2
dt=0.01
d=1
I obtain for the C code, for the last k:
where from the cython code:
I really can't find the problem in the code. Where could a bug be present?
Update
If I run the code with d=0 (which means that the "bruit part" can be neglected) I still obtain different results:
Histogram for d=0
The blu is the C simulation and the other colors are three simulations from python.
This means that there's something wrong in this section:
for kt in range(kt_max-1):
for i in range(N):
S1 = 0.0
for j in range(N):
x_diff = xt[j,kt] - xt[i,kt]
S1 = S1 + sin(x_diff)
xtilde = xt[i,kt] + ((K/N)*S1)*dt
xt[i,kt+1] = xtilde%(2*np.pi)
Any ideas? Has the function sin some tricky argument to put in the code?
I've also done the computation of the sin sum, getting:
sin sum simulations
(black is C code, the rest is python simulations)

Single cycle MIPS processor instruction execution

I am executing six instructions in this Single Cycle MIPS processor.
I am unable to figure error in ALU module.
Six instructions i am trying to execute are: Add, Sub, AND, OR, Load, Store
Right now, i am getting correct result for Addition only.
In five bit MUX, i have given an input 'a' and 'b'. How can i relate this input 'a' and 'b' to instruction source and detonation registers.
Also, how can i add 4 byte after the execution of each instruction (i.e. my program counter is unable to increment).
//ALU Block
module ALU (FunctField,ReadData1,out_inALU, ALUOp,ctr1,result);
input ALUOp;
input [5:0]FunctField;
input [31:0] ReadData1;
input [31:0] out_inALU;
output [2:0] ctr1;
reg [2:0] ctr1;
output [31:0] result;
reg [31:0] result;
always #(*)
begin
if(ALUOp == 1) //Arithmetic' Type Instructions
begin
case(FunctField)
//begin
6'b100000: ctr1 = 3'b010; //ADDITION in 'R' Type
6'b100010: ctr1 = 3'b110; // SUBTRACTION in 'R' Type
6'b100100: ctr1 = 3'b000; // AND in 'R' Type
6'b100101: ctr1 = 3'b001; // OR in 'R' Type
endcase
end
if(ALUOp == 0)
begin // LW/SW Type Instructions
if (ctr1 == 3'b010)
result = ReadData1 + out_inALU ;
else if (ctr1 == 3'b110)
result = ReadData1 - out_inALU ;
else if (ctr1 == 3'b000)
result = ReadData1 & out_inALU ;
else if (ctr1 == 3'b001)
result = ReadData1 | out_inALU;
end
result = ReadData1 | out_inALU ;
end
endmodule
// Data memory
module data_memory (ReadAddr, WriteAddr, WriteData1, clock,
MemWrite, MemRead,ReadData);
input [31:0] ReadAddr, WriteAddr, WriteData1;
input clock, MemWrite, MemRead;
reg [31:0] mem[0:50]; // For simulation this no. is enough
reg [31:0] i; // Temporary variable
output [31:0] ReadData;
reg [31:0] ReadData;
initial
begin
// Initial read-out
ReadData = 0;
// Initial memory content for testing purpose
for ( i = 0; i <= 50; i = i+1)
mem[i] = i;
end
// Memory content is always fetched with positive edge clock
always #(posedge clock)
begin
wait ( MemRead )
#10 ReadData = mem[ReadAddr];
wait ( MemWrite )
#10 mem[WriteAddr] = WriteData1;
end
endmodule
// Instruction Memory
module inst(addr,clock,instruction);
input clock;
input [ 31 : 0 ] addr;
output [ 31 : 0 ] instruction;
reg [ 31 : 0 ] instruction;
reg [ 31 : 0 ] MEM[0 :31 ] ;
initial
begin
MEM[ 0 ] <= 32'h10000011;
MEM[ 1 ] <= 32'h10000011 ;
MEM[ 2 ] <= 32'h20000022 ;
MEM[ 3 ] <= 32'h30000033 ;
MEM[ 4 ] <= 32'h40000044 ;
MEM[ 5 ] <= 32'h50000055 ;
MEM[ 6 ] <= 32'h60000066 ;
MEM[ 7 ] <= 32'h70000077 ;
MEM[ 8 ] <= 32'h80000088 ;
MEM[ 9 ] <= 32'h90000099 ;
end
always #( posedge clock )
begin
instruction <= MEM[ addr ] ;
end
endmodule
//Main module
module(reset, clock, regwrite,regDst,ALUSrc,MemtoReg,MemWrite,MemRead, input_PC)
input reset,clock;
input regWrite;
input regDst;
input ALUSrc;
input MemtoReg;
input MemWrite;
input MemRead;
input [31:0] input_PC;
wire [4:0] ReadReg1, ReadReg2, WriteReg;
wire [31:0] WriteData;
// Instantiation of modules
//Program Counter
wire [31:0] addr;
PC x1(input_PC,clock,reset,addr);
// Instruction Memory
wire [31:0] instruction;
inst x2(addr,clock,instruction);
//Multiplexer with regDst
reg[4:0] inputa,inputb;
MUX_2to1_5bit x3(inputa,inputb,regDst,WriteReg);
//Register File
wire [31:0] ReadData1,ReadData2;
Register_32 x4 ( ReadReg1, ReadReg2, WriteReg, WriteData, clock,
RegWrite,ReadData1, ReadData2);
//Sign Extender
wire [31:0] out_sign;
SignExtender_16to32 x5(immediate, out_sign);
//Multilpexer ALUSrc
wire [31:0] out_inALU;
MUX_2to1 x6( ReadData2 , out_sign, ALUSrc,out_inALU );
//ALU
wire [31:0] result;
wire [2:0] ctr1;
ALU x7 (FunctField,ReadData1,out_inALU, ALUOp,ctr1,result);
//Data Memory
reg [31:0] ReadAddr;
reg [31:0] WriteAddr;
wire [31:0] ReadData;
data_memory x8(ReadAddr, WriteAddr, WriteData, clock, MemWrite,
MemRead,ReadData);
//Multiplexer MemtoReg
MUX_2to1_memreg x9( result,ReadData,MemtoReg,WriteData);
endmodule
// Mux2 to 1_32 bit
module MUX_2to1( ReadData2 , outputData, ALUSrc,out_inALU );
input [31:0] ReadData2,outputData;
input ALUSrc;
output [31:0]out_inALU;
reg [31:0]out_inALU;
always #(ReadData2 or outputData or ALUSrc )
begin
case(ALUSrc)
1'b0: out_inALU=ReadData2;
1'b1: out_inALU=outputData;
endcase
end
endmodule
// Mux 2 to 1 5 bit
module MUX_2to1_5bit( inputa , inputb, regDst, WriteReg);
input [4:0] inputa, inputb;
input regDst;
output [4:0]WriteReg;
reg [4:0]WriteReg;
always #(inputa or inputb or regDst )
begin
case(regDst)
1'b0: WriteReg=inputa;
1'b1: WriteReg=inputb;
endcase
end
endmodule
// Mux 2 to 1 for memory register
module MUX_2to1_memreg( result,ReadData,MemtoReg,WriteData);
input [31:0] ReadData,result;
input MemtoReg;
output [31:0] WriteData;
reg [31:0]WriteData;
always #(* )
begin
case(MemtoReg)
1'b0: WriteData= result ;
1'b1: WriteData= ReadData;
endcase
end
endmodule
// Progrma COunter
module PC(input_PC,clock,reset,addr);
input reset,clock;
input [31:0] input_PC;
output reg [31:0] addr;
always #(posedge clock)
begin
if (reset)
addr=0;
else
addr=input_PC+4;
end
endmodule
//Register
module Register_32 ( ReadReg1, ReadReg2, WriteReg,
WriteData, clock, RegWrite,ReadData1, ReadData2);
input [4:0] ReadReg1, ReadReg2, WriteReg;
input [31:0] WriteData;
input clock, RegWrite;
output [31:0] ReadData1, ReadData2;
reg [31:0] ReadData1, ReadData2;
reg [31:0] mem[0:31]; // 32 32-bit registers
reg [5:0] i; // Temporary variable
initial
begin
// Initial registers for testing purpose
for ( i = 0; i <= 31; i = i+1)
mem[i] = i;
// Initial start-up
ReadData1 = 0;
ReadData2 = 0;
end
// Data from register is always fetched with positive edge clock
always #(posedge clock)
begin
#1 ReadData1 = mem[ReadReg1];
#1 ReadData2 = mem[ReadReg2];
if ( RegWrite == 1)
#1 mem[WriteReg] = WriteData;
end
endmodule
// Sign extender
module SignExtender_16to32(immediate,out_sign);
input[15:0] immediate;
output[31:0] out_sign;
reg [31:0] out_sign;
always#(*)
begin
out_sign[15:0] = immediate[15:0];
out_sign[31:16] = {16{immediate[15]}};
end
endmodule
You could increment the program counter as below but it will have wrap around issues. Better to have a signal to latch the input address or at reset do add = input_PC;
module PC(input_PC,clock,reset,addr);
input reset,clock;
input [31:0] input_PC;
output reg [31:0] addr;
always #(posedge clock)
begin
if (reset)
addr= 0;
else
addr=input_PC+4+addr;
end
endmodule
you would want the mem to ignore lower 2 bits in inst module else after reading mem 0 it will read mem[4] .
instruction <= MEM[ addr[31:2] ] ;
You need to connect the instruction to the ALU module , cannot offer any suggestion as i cannot figure what your instruction decoding scheme is.

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