Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Is this an efficient Verilog code

Status
Not open for further replies.

David83

Advanced Member level 1
Joined
Jan 21, 2011
Messages
410
Helped
45
Reputation
92
Reaction score
45
Trophy points
1,308
Activity points
3,639
Hello all,

I tried to write the design and stimulus blocks for a 2-bit mux using structural modeling. I wrote the modules as following:

Code:
// 1-bit Mux 

module mux(out,S,A,B);

input A,B,S;
output out;

not (S_n,S);
and (I1,A,S_n);
and (I2,B,S);

or (out,I1,I2);

endmodule


module mux2bit(Out,S,A,B);

input S;
input [1:0] A;
input [1:0] B;

output [1:0] Out;

mux MUX1(Out[1],S,A[1],B[1]);
mux MUX2(Out[0],S,A[0],B[0]);

endmodule

// Testbench for 2-bit MUX
`timescale 1ns/1ns
module mux_tb;

reg clk;
reg [1:0] A;
reg [1:0] B;
reg S;
wire [1:0] out;

initial
begin
clk=1;
S=0;
A=2'b11;
B=2'b00;
end

always #5 clk=~clk;

always #40 S=~S;

always @(posedge clk)
begin
A=A+1;
B=B+1;
end

mux2bit MUT(out,S,A,B);

endmodule

I did functional verification, and the design block is working fine. The total system's schematic, as well as the schematic of MUX1, I obtained from Vivado are attached. I just wonder if any of the three modules could have be written more efficiently. Any hint about this?

Thanks
 

Attachments

  • schematic2BitMux.pdf
    9.1 KB · Views: 58
  • schematicMux1.pdf
    9.2 KB · Views: 55

It depends on what kind of efficiency you are looking for. If you want to save typing, you should be using the ANSI-style module port declarations.

// 1-bit Mux

Code:
module mux(output out, input S,A,B);

not (S_n,S);
and (I1,A,S_n);
and (I2,B,S);

or (out,I1,I2);

endmodule

module mux2bit(output [1:0] Out,input S, wire [1:0] A,B);

output [1:0] Out;

mux MUX[1:2](Out,S,A,B); // array of instances.

endmodule
 

I meant in everything, including the testbench, and if I could have written it to be more illustrative. I used my basic knowledge to write it.
 

I meant in everything, including the testbench, and if I could have written it to be more illustrative. I used my basic knowledge to write it.

To make the testbench complete, you really should make it self checking. ie. have some code that checks that the output is correct.
 

You will need a "model" of the design so that you know what should happen"


Code Verilog - [expand]
1
2
always @(posedge clk)
  if( op != expected ) $display("Output error at clock %d", clk_cnt++);



Ill leave it as an exercise to generate op and expected values.
 
Hello all,

I tried to write the design and stimulus blocks for a 2-bit mux using structural modeling. I wrote the modules as following:

Code:
// 1-bit Mux 

module mux(out,S,A,B);

input A,B,S;
output out;

not (S_n,S);
and (I1,A,S_n);
and (I2,B,S);

or (out,I1,I2);

endmodule


module mux2bit(Out,S,A,B);

input S;
input [1:0] A;
input [1:0] B;

output [1:0] Out;

mux MUX1(Out[1],S,A[1],B[1]);
mux MUX2(Out[0],S,A[0],B[0]);

endmodule

// Testbench for 2-bit MUX
`timescale 1ns/1ns
module mux_tb;

reg clk;
reg [1:0] A;
reg [1:0] B;
reg S;
wire [1:0] out;

initial
begin
clk=1;
S=0;
A=2'b11;
B=2'b00;
end

always #5 clk=~clk;

always #40 S=~S;

always @(posedge clk)
begin
A=A+1;
B=B+1;
end

mux2bit MUT(out,S,A,B);

endmodule

I did functional verification, and the design block is working fine. The total system's schematic, as well as the schematic of MUX1, I obtained from Vivado are attached. I just wonder if any of the three modules could have be written more efficiently. Any hint about this?

Thanks

My general notes:
1.) Structural design is more popular as an educational tool.
2.) While I prefer the outputs-than-inputs style, I feel that I am in the minority.
3.) Use Verilog2001 style port declarations, and place each input/output on a new line. The intent is to make it easier to copy/paste the component while making it easier to read.
4.) It is odd to have a space between an instance/function and the parenthesis.
5.) I also prefer spaces after a comma.
6.) For MUX1/MUX2, use named connections -- (.out(OUT[1]), .S(S), .A(A[1]), .B(B[1])).
7.) Ideally, they would be on the different lines.
8.) consider learning about generates, and use a for-generate construct for the MUX's.

The design is small enough that my comments are all of minor concern. #6 is important -- modules tend to have a dozen or more ports. It is easy to get an incorrect order or even figure out which signal is connected to which port. #3/#7 are related as it allows block copy/paste to work quickly.

For the testbench, use <= for the assignments to A,B.



Verilog has more anti-features than VHDL. It is best to learn about these bad practices and systemically avoid them.
 

My general notes:
1.) Structural design is more popular as an educational tool.
2.) While I prefer the outputs-than-inputs style, I feel that I am in the minority.
3.) Use Verilog2001 style port declarations, and place each input/output on a new line. The intent is to make it easier to copy/paste the component while making it easier to read.
4.) It is odd to have a space between an instance/function and the parenthesis.
5.) I also prefer spaces after a comma.
6.) For MUX1/MUX2, use named connections -- (.out(OUT[1]), .S(S), .A(A[1]), .B(B[1])).
7.) Ideally, they would be on the different lines.
8.) consider learning about generates, and use a for-generate construct for the MUX's.

The design is small enough that my comments are all of minor concern. #6 is important -- modules tend to have a dozen or more ports. It is easy to get an incorrect order or even figure out which signal is connected to which port. #3/#7 are related as it allows block copy/paste to work quickly.

For the testbench, use <= for the assignments to A,B.



Verilog has more anti-features than VHDL. It is best to learn about these bad practices and systemically avoid them.

2- What do you mean by you "prefer output-than-input" style?
4- Do you mean like and(out,in1,in2) instead of and (out,in1,in2)?
6- I still do know how to use this. So, the port after '.' in the instantiation process is a port in the instantiated module? Also, I guess they don't have to be of the same name, right? Like if I defined
Code:
output [1:0] C;
instead of
Code:
output [1:0] Out;
and then wrote
Code:
mux MUX1(.out(C[1]),...)
that would be fine, right?
8- What do you mean "generates" and "for-generate"? Also what does construct mean in Verilog?

What is the difference between '=' and '<='?

Thanks
 

What is the difference between '=' and '<='?

Have you studied about blocking and nonblocking statements in verilog?
Consult a good Verilog textbook.
 

I'm reading one, but haven't encountered this yet.
 

My general notes:
1.) Structural design is more popular as an educational tool.
2.) While I prefer the outputs-than-inputs style, I feel that I am in the minority.
3.) Use Verilog2001 style port declarations, and place each input/output on a new line. The intent is to make it easier to copy/paste the component while making it easier to read.
4.) It is odd to have a space between an instance/function and the parenthesis.
5.) I also prefer spaces after a comma.
6.) For MUX1/MUX2, use named connections -- (.out(OUT[1]), .S(S), .A(A[1]), .B(B[1])).
7.) Ideally, they would be on the different lines.
8.) consider learning about generates, and use a for-generate construct for the MUX's.

The design is small enough that my comments are all of minor concern. #6 is important -- modules tend to have a dozen or more ports. It is easy to get an incorrect order or even figure out which signal is connected to which port. #3/#7 are related as it allows block copy/paste to work quickly.

For the testbench, use <= for the assignments to A,B.



Verilog has more anti-features than VHDL. It is best to learn about these bad practices and systemically avoid them.

I don't entirely agree with 6 or 7. In this case there are few enough ports that 6 isn't much of a burden but in cases where there are repetitive module declarations (like synchronizing 100+ async input pins) I believe it makes far more readable code if the declarations are on one line with ports tabbed so they line up in columns. This makes it much easier for a human to discern patterns or pick out a mistake.

If the additional text of named connections compromises readability by, say, pushing things off the right side of the screen I think it's a reasonable compromise to skip it (I'll use a comment line at the top to describe the port for each column).
 

Perhaps, but the number of times this comes up is negligible. Even your example makes me think you should be either inferring the logic or using a for-generate.
 

...
6.) For MUX1/MUX2, use named connections -- (.out(OUT[1]), .S(S), .A(A[1]), .B(B[1]))....

I noticed that when I use this style, I have to use it through all modules or the compiler will give me an error, it that right?
 

I'm not sure, using positional connections is something that I've only seen from student designs or code generating programs. Everything I've worked on only used named connections.

That said, I do think you can't mix named and positional connections. Again, not something I'm sure about as I've only used named connections once I learned about it.
 
You can't mix named and positional port connections within the same instance. But you have the choice for each instance.
 

I meant for different instances, not the same instance. When I used positional and named connections for different instances, I got an error, but when I used named connections for all instances of different module levels, it worked!!
 

Show the code and the error.

You were right, I tried different connection styles for different instances again and it worked. Probably in the first time I mixed the two styles for the same instance by mistake.
 

I'm not sure, using positional connections is something that I've only seen from student designs or code generating programs. Everything I've worked on only used named connections.

That said, I do think you can't mix named and positional connections. Again, not something I'm sure about as I've only used named connections once I learned about it.

Ive worked with people where the coding standard for Verilog insisted on positional association, short signal names and #delays for EVERY assignment (along with 80 character line limit). As a usual VHDL developer I found this VERY odd.
 

Ive worked with people where the coding standard for Verilog insisted on positional association, short signal names and #delays for EVERY assignment (along with 80 character line limit). As a usual VHDL developer I found this VERY odd.
You must have worked with really bad Verilog coders, my personal Verilog coding standards forbid all of those things!

Even my line length allows for 100 characters, fits two files side by side in a single instance of Vim on a 16:9 monitor at the font size I use.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top