ASIC-WORLD Verilog (7) procedural statements

written in front

        Before I was going to write some simple verilog tutorials, I consulted a lot of materials - this set of verilog tutorials on the asic-world website is one of them. This set of tutorials is very well written, but there is no Chinese, so I have to boldly translate it (with my own understanding) and share it with everyone.

        This is the original text of the website: Verilog Tutorial

        This is the series navigator: Verilog Tutorial Series Article Navigator

Verilog's level of abstraction

  • Behavioral Models: higher level modeling for modeling logical behavior
  • RTL Models (RTL Models): logic is modeled at the register level
  • Structural Models: Logic is modeled at both the register level and the gate level

Procedural Blocks

        Verilog behavioral code is inside procedural blocks, with one exception: some behavioral code also exists outside procedural blocks. We can understand this in detail as the article progresses.

        There are two types of procedural blocks in Verilog:         

  • initial : initial is only executed once at time zero (executed from time zero)
  • always : The always loop executes over and over again; as the name suggests, it always executes

Example usage of initial

module initial_example();
reg clk,reset,enable,data;

initial begin
 clk = 0;
 reset = 0;
 enable = 0;
 data = 0;
end

endmodule

        In the example above, the execution of initial starts at time 0. After the statement in initial is executed once, it will not be executed again.

always  usage example

module always_example();
reg clk,reset,enable,q_in,data;

always @ (posedge clk)
if (reset)  begin
   data <= 0;
end else if (enable) begin   
   data <= q_in;
end

endmodule

        In always, when the trigger event occurs, the code in begin and end will be executed; then wait for the next event to trigger again. This process of waiting and executing events is repeated until the simulation stops.

procedure assignment statement

  • Procedure assignment statements can assign values ​​to reg, integer, real, and time variables, but not to net (wire data type)
  • You can assign a net (wire), a constant, another register, or a specific value to a register (reg data type)

       

        The following code is wrong: the wire variable is assigned a value in initial.

module initial_bad();
reg clk,reset;
wire enable,data;

initial begin
 clk = 0;
 reset = 0;
 enable = 0;
 data = 0;
end

endmodule

        The following code is correct: only the reg variable is assigned in initial.

module initial_good();
reg clk,reset,enable,data;

initial begin
 clk = 0;
 reset = 0;
 enable = 0;
 data = 0;
end

endmodule

        If multiple procedural assignment statements need to be implemented at the same time, these statements must be contained within:

  • in the begin-end block of the sequence
  • in parallel fork-join blocks

Examples of begin-end statements

        begin-end is executed sequentially, so the assignment statements will be executed one by one in chronological order - assigning value to clk at time 1, assigning value to reset at time 1+10, assigning value to enable at time 1+10+5, and so on...

module initial_begin_end();
reg clk,reset,enable,data;

initial begin
 $monitor(
   "%g clk=%b reset=%b enable=%b data=%b", 
   $time, clk, reset, enable, data);
 #1  clk = 0;
 #10 reset = 0;
 #5  enable = 0;
 #3  data = 0;
 #1 $finish;
end

endmodule

        The simulation result of this code is as follows:

0  clk=x reset=x  enable=x  data=x
1  clk=0 reset=x  enable=x  data=x
11 clk=0 reset=0 enable=x  data=x
16 clk=0 reset=0 enable=0  data=x
19 clk=0 reset=0 enable=0  data=0

Example of fork-join statement

        fork-join is executed sequentially, so the assignment statement will be executed at the same time - assigning a value to clk at time 1, assigning a value to reset at time 10, assigning a value to enable at time 5, and so on...

module initial_fork_join();
reg clk,reset,enable,data;

initial begin
 $monitor("%g clk=%b reset=%b enable=%b data=%b", 
   $time, clk, reset, enable, data);
 fork
   #1  clk = 0;
   #10 reset = 0;
   #5  enable = 0;
   #3  data = 0;
 join
 #1 $display ("%g Terminating simulation", $time);
 $finish;
end

endmodule

        The simulation result of this code is as follows:

0 clk=x reset=x enable=x data=x
1 clk=0 reset=x enable=x data=x
3 clk=0 reset=x enable=x data=0
5 clk=0 reset=x enable=0 data=0
10 clk=0 reset=0 enable=0 data=0
11 Terminating simulation

Blocking assignment and non-blocking assignment ( Blocking and Nonblocking assignment )

        Blocking assignments are executed sequentially, and they block the execution of the next statement until the current statement is executed, so they are called blocking assignments. Use the symbol "=" for assignment, example: a = b;

        Non-blocking assignments are executed in parallel, and the execution of the next statement will not be blocked by the execution of the current statement, so they are called non-blocking statements. Use the symbol "<=" for assignment, example: a <= b;

        Let's look at an example:

module blocking_nonblocking();

reg a,b,c,d;
// Blocking Assignment
initial begin
  #10 a = 0;
  #11 a = 1;
  #12 a = 0;
  #13 a = 1;
end

initial begin
  #10 b <= 0;
  #11 b <= 1;
  #12 b <= 0;
  #13 b <= 1;
end

initial begin
   c = #10 0;
   c = #11 1;
   c = #12 0;
   c = #13 1;
end

initial begin
   d <= #10 0;
   d <= #11 1;
   d <= #12 0;
   d <= #13 1;
end

initial begin
  $monitor("TIME = %g a = %b b = %b c = %b d = %b",$time, a, b, c, d);
  #50 $finish;
end

endmodule

        Here are the simulation results and simulated waveforms:

TIME = 0   a = x b = x c = x  d = x
TIME = 10 a = 0 b = 0 c = 0 d = 0
TIME = 11 a = 0 b = 0 c = 0 d = 1
TIME = 12 a = 0 b = 0 c = 0 d = 0
TIME = 13 a = 0 b = 0 c = 0 d = 1
TIME = 21 a = 1 b = 1 c = 1 d = 1
TIME = 33 a = 0 b = 0 c = 0 d = 1
TIME = 46 a = 1 b = 1 c = 1 d = 1

Guess you like

Origin blog.csdn.net/wuzhikaidetb/article/details/130119879