Reputation: 1863
I have written the following code in Verilog using gates:
`timescale 1ns / 1ps
module flip_flop (d,clk,q,q_bar);
input [36:0] d;
input clk;
output [36:0] q;
output [36:0] q_bar;
wire dbar,x,y;
not(dbar,d);
nand(x,clk,d);
nand(y,clk,dbar);
nand(q,q_bar,y);
nand(q_bar,q,x);
endmodule
module adder(A,B,S);
input [36:0] A;
input [36:0] B;
output [36:0] S;
assign S = A + B;
endmodule
module subtractor(A,B,S);
input [36:0] A;
input [36:0] B;
output [36:0] S;
assign S = A - B;
endmodule
module dec256sinc24b
(input mclk1, /* used to clk filter */
input reset, /* used to reset filter */
input mdata1, /* input data to be filtered */
output reg [15:0] DATA, /* filtered output*/
output reg data_en,
input [15:0] dec_rate
);
reg [36:0] MOUT;
reg [36:0] delta1;
reg [36:0] CNN1;
reg [36:0] CN1;
reg [36:0] CNN2;
reg [36:0] CN2;
reg [36:0] DN0;
reg [36:0] DN1;
reg [36:0] CN3;
reg [36:0] DN3;
reg [36:0] CN4;
reg [36:0] DN5;
reg [36:0] CN5;
reg [15:0] word_count;
reg word_clk;
reg enable;
/*Perform the Sinc action*/
always @ (mdata1)
if(mdata1==0)
MOUT <= 37'd0;
/* change 0 to a -1 for twos complement */
else
MOUT <= 37'd1;
/*decimation stage (MCLKOUT/WORD_CLK) */
always @ (negedge mclk1, posedge reset)
begin
if (reset)
word_count <= 16'd0;
else
begin
if ( word_count == dec_rate - 1 )
word_count <= 16'd0;
else
word_count <= word_count + 16'b1;
end
end
always @ ( negedge mclk1, posedge reset )
begin
if ( reset )
word_clk <= 1'b0;
else
begin
if ( word_count == dec_rate/2 - 1 )
word_clk <= 1'b1;
else if ( word_count == dec_rate - 1 )
word_clk <= 1'b0;
end
end
flip_flop M1(.d(MOUT),.clk(mclk1),.q(delta1));
adder M2(.A(CN1),.B(delta1),.S(CNN1));
flip_flop M3(.d(CNN1),.clk(mclk1),.q(CN1));
adder M4(.A(CN2),.B(CN1),.S(CNN2));
flip_flop M5(.d(CNN2),.clk(mclk1),.q(CN2));
flip_flop M6(.d(CN2),.clk(word_clk),.q(DN0));
flip_flop M7(.d(DN0),.clk(word_clk),.q(DN1));
subtractor M8(.A(DN0),.B(DN1),.S(CN3));
flip_flop M9(.d(CN3),.clk(word_clk),.q(DN3));
subtractor M10(.A(CN3),.B(DN3),.S(CN4));
flip_flop M11(.d(CN4),.clk(word_clk),.q(DN5));
subtractor M12(.A(CN4),.B(DN5),.S(CN5));
/* Clock the Sinc output into an output register
WORD_CLK = output word rate */
always @ (negedge word_clk )
begin
case ( dec_rate )
16'd32:begin
DATA <= (CN5[15:0] == 16'h8000) ? 16'hFFFF : {CN5[14:0], 1'b0};
end
16'd64:begin
DATA <= (CN5[18:2] == 17'h10000) ? 16'hFFFF : CN5[17:2];
end
16'd128:begin
DATA <= (CN5[21:5] == 17'h10000) ? 16'hFFFF : CN5[20:5];
end
16'd256:begin
DATA <= (CN5[24:8] == 17'h10000) ? 16'hFFFF : CN5[23:8];
end
16'd512:begin
DATA <= (CN5[27:11] == 17'h10000) ? 16'hFFFF : CN5[26:11];
end
16'd1024:begin
DATA <= (CN5[30:14] == 17'h10000) ? 16'hFFFF : CN5[29:14];
end
16'd2048:begin
DATA <= (CN5[33:17] == 17'h10000) ? 16'hFFFF : CN5[32:17];
end
16'd4096:begin
DATA <= (CN5[36:20] == 17'h10000) ? 16'hFFFF : CN5[35:20];
end
default:begin
DATA <= (CN5[24:8] == 17'h10000) ? 16'hFFFF : CN5[23:8];
end
endcase
end
/* Synchronize Data Output*/
always@ (negedge mclk1, posedge reset )
begin
if ( reset )
begin
data_en <= 1'b0;
enable <= 1'b1;
end
else
begin
if ( (word_count == dec_rate/2 - 1) && enable )
begin
data_en <= 1'b1;
enable <= 1'b0;
end
else if ( (word_count == dec_rate - 1) && ~enable )
begin
data_en <= 1'b0;
enable <= 1'b1;
end
else
data_en <= 1'b0;
end
end
endmodule
But, I am getting the following errors while running the code:
primitive output connection must be a scalar net at line 12 (nand(q,q_bar,y);)
static elaboration of top level verilog design unit(s) in library work failed
I would appreciate if anyone could please let me know what are the issues in my code.
Upvotes: 1
Views: 3620
Reputation: 62045
There are several issues in your code.
The error message means that you can not connect a 37-bit vector net (q
) to the output port of the nand
primitive gate instance.
The Verilog built-in gate primitives are different from modules in this respect. Modules support multi-bit ports, but primitives only support single-bit ports when you instantiate a single gate.
However, primitives do support instance arrays where the primitive keyword is followed by an instance name and a range specifier. You can fix the syntax error by changing:
nand(q,q_bar,y);
to:
nand n1 [36:0] (q,q_bar,y);
Refer to IEEE Std 1800-2017, section 28.3.6 Primitive instance connection list.
Another likely problem is that the following line probably does not do what you want:
not(dbar,d);
d
is 37 bits, whereas dbar
is a single bit.
Also, x
and y
are single bit. You should check all your connections.
Finally, it is notoriously difficult to model flip flops using primitives like this in Verilog because flip flops are feedback circuits. Save yourself a lot of trouble and use the appropriate modeling style: behavioral using @(posedge clk)
like you are doing elsewhere in your code.
Upvotes: 2
Reputation: 191
You cannot use a multi-bit operation on primitives
here nand(q,q_bar,y);
can be used for single bit. Try using a genvar.
Also the net y
is single bit so check if that's correct because eventually y
will settle to y = ~(q[36] & q[36]);
genvar i;
generate
for(i=0i<37;i++)
nand(q[i],q_bar[i],y);
endgenerate
Upvotes: 0