|
|
|
|
|
|
|
|
|
|
|
|
Synchronization of Signals
|
|
|
Synchronization of signals in Vera can be done in three ways. |
|
|
|
|
|
|
|
|
|
|
|
We will be looking each of this in detail. |
|
|
|
|
|
Implicit Synchronization
|
|
|
The drive, sample, and expect primitives perform implicit synchronization to the interface CLOCK. That means that the clock is advanced only when it is necessary to perform the next signal operation. |
|
|
|
|
|
In the example below, output signals are driven at the postive edge of the interface clock, and input signals are sampled at the negative edge of the interface clock. Thus, the following code advances the simulation cycle a half cycle per statement even though a delay is not specified. |
|
|
|
|
|
Example : Implicit Synchronization
|
|
|
|
|
|
1 #include "vera_defines.vrh"
2
3 // This is what connects with HDL
4 interface mem_if {
5 input clock CLOCK;
6 output [7:0] addr PHOLD #1;
7 input [7:0] rdata NSAMPLE #-1;
8 output [7:0] wdata NHOLD #1;
9 output wr NHOLD #1;
10 output rd NHOLD #1;
11 }
12
13 // Top level program
14 program implicit {
15 bit [7:0] data = 0;
16 integer i;
17 mem_if.wr = 0;
18 mem_if.rd = 0;
19 repeat(10) @ (posedge mem_if.clock);
20 for (i=0; i < 10; i++) {
21 mem_if.addr = i;
22 data = random() + 10;
23 mem_if.wdata = data;
24 mem_if.wr = 1;
25 printf("Writing address %0x, with data %0x\n",i,data);
26 }
27 for (i=0; i < 10; i++) {
28 mem_if.addr = i;
29 mem_if.rd = 1;
30 mem_if.wr = 0;
31 printf("Reading address %0x",i);
32 printf(", data %0x\n",mem_if.rdata);
33 }
34 }
You could download file implicit.vr here
|
|
|
|
|
|
Verilog |
|
|
1 module implicit_verilog ();
2 // Internal variables
3 reg clk;
4 reg [7:0] mem [0:255];
5 wire [7:0] rdata;
6
7 wire [7:0] addr;
8 wire [7:0] wdata;
9 wire wr,rd;
10
11 assign rdata = (rd) ? mem[addr] : 8'b0;
12
13 always @ (addr or wr or wdata)
14 if (wr) mem[addr] = wdata;
15
16 // Connect the program here
17 implicit vshell(
18 .SystemClock (clk),
19 .\mem_if.clock (clk),
20 .\mem_if.addr (addr),
21 .\mem_if.rdata (rdata),
22 .\mem_if.wdata (wdata),
23 .\mem_if.wr (wr),
24 .\mem_if.rd (rd)
25 );
26 // Init all the variables
27 initial begin
28 clk = 0;
29 end
30 // Clock generator
31 always #1 clk = ~clk;
32
33 endmodule
You could download file implicit.v here
|
|
|
|
|
|
Run the above example with waveform dump on and look at the waveform to understand how implicit works. |
|
|
|
|
|
Simulation : Implicit Synchronization
|
|
|
There is mistakes in above vera code, thats the reason few bytes read back don't match with write values. |
|
|
|
|
|
Writing address 0, with data b6
Writing address 1, with data 27
Writing address 2, with data c9
Writing address 3, with data d3
Writing address 4, with data 67
Writing address 5, with data 74
Writing address 6, with data 50
Writing address 7, with data 4d
Writing address 8, with data 69
Writing address 9, with data 1f
Reading address 0, data 0
Reading address 1, data 1f
Reading address 2, data 27
Reading address 3, data c9
Reading address 4, data d3
Reading address 5, data 67
Reading address 6, data 74
Reading address 7, data 50
Reading address 8, data 4d
Reading address 9, data 69
|
|
|
|
|
|
|
|
|
|
|
|
Explicit Synchronization
|
|
|
The synchronization operator (@) is used to perform explicit synchronization. That is, you are explicitly synchronizing to the signal changing value. |
|
|
|
|
|
You can use the or keyword to specify multiple interface signals. If you specify more than one signal, the synchronization occurs on the next change of any of the listed signals. |
|
|
|
|
|
Example : Explicit Synchronization
|
|
|
|
|
|
1 #include "vera_defines.vrh"
2
3 // This is what connects with HDL
4 interface mem_if {
5 input clock CLOCK;
6 output [7:0] addr PHOLD #1;
7 input [7:0] rdata NSAMPLE #-1;
8 output [7:0] wdata NHOLD #1;
9 output wr NHOLD #1;
10 output rd NHOLD #1;
11 input heart_beat PSAMPLE #-1;
12 }
13
14 // Top level program
15 program explicit {
16 bit [7:0] data = 0;
17 integer i;
18 mem_if.wr = 0;
19 mem_if.rd = 0;
20 repeat(10) @ (posedge mem_if.clock);
21 for (i=0; i < 10; i++) {
22 @ (posedge mem_if.heart_beat);
23 mem_if.addr = i;
24 data = random() + 10;
25 mem_if.wdata = data;
26 mem_if.wr = 1;
27 printf("%0dns Writing address %0x, with data %0x\n",get_time(LOW), i,data);
28 @ (posedge mem_if.heart_beat);
29 mem_if.wr = 0;
30 }
31 @ (CLOCK);
32 for (i=0; i < 10; i++) {
33 @ (posedge mem_if.heart_beat or mem_if.clock);
34 mem_if.addr = i;
35 mem_if.rd = 1;
36 mem_if.wr = 0;
37 @ (negedge mem_if.clock);
38 printf("%0dns Reading address %0x",get_time(LOW),i);
39 printf(", data %0x\n",mem_if.rdata);
40 @ (posedge mem_if.clock);
41 mem_if.rd = 0;
42 }
43 }
You could download file explicit.vr here
|
|
|
|
|
|
Verilog |
|
|
1 module explicit_verilog ();
2 // Internal variables
3 reg clk;
4 reg [7:0] mem [0:255];
5 wire [7:0] rdata;
6
7 wire [7:0] addr;
8 wire [7:0] wdata;
9 wire wr,rd;
10 reg heart_beat;
11
12
13 assign rdata = (rd) ? mem[addr] : 8'b0;
14
15 always @ (addr or wr or wdata)
16 if (wr) mem[addr] = wdata;
17
18 // Connect the program here
19 explicit vshell(
20 .SystemClock (clk),
21 .\mem_if.clock (clk),
22 .\mem_if.addr (addr),
23 .\mem_if.rdata (rdata),
24 .\mem_if.wdata (wdata),
25 .\mem_if.wr (wr),
26 .\mem_if.rd (rd),
27 .\mem_if.heart_beat (heart_beat)
28 );
29 // Init all the variables
30 initial begin
31 clk = 0;heart_beat = 0;
32 end
33 // Clock generator
34 always #1 clk = ~clk;
35
36 always @ (posedge clk)
37 heart_beat = ~heart_beat;
38
39 endmodule
You could download file explicit.v here
|
|
|
|
|
|
Simulation : Explicit Synchronization
|
|
|
|
|
|
24ns Writing address 0, with data b6
32ns Writing address 1, with data 27
40ns Writing address 2, with data c9
48ns Writing address 3, with data d3
56ns Writing address 4, with data 67
64ns Writing address 5, with data 74
72ns Writing address 6, with data 50
80ns Writing address 7, with data 4d
88ns Writing address 8, with data 69
96ns Writing address 9, with data 1f
106ns Reading address 0, data b6
112ns Reading address 1, data 27
118ns Reading address 2, data c9
124ns Reading address 3, data d3
130ns Reading address 4, data 67
136ns Reading address 5, data 74
142ns Reading address 6, data 50
148ns Reading address 7, data 4d
154ns Reading address 8, data 69
160ns Reading address 9, data 1f
|
|
|
|
|
|
Asynchronous Signal Operations
|
|
|
When modelling complex timing, it may not always be possible to just live with implicit and explicit synchronization, So Vera provides Async Modifier. Async Modifiers basically allows the operation (sample/drive) to happen immediately with out waiting for clock event in interface. |
|
|
|
|
|
Below table shows all the three places where async modifier can be used. |
|
|
|
|
|
synchronization
|
@(signal_name async);
|
Drive
|
signal_name range drive_operator expression async;
|
Sample
|
variable = signal_name async;
|
Expect
|
expect_list async;
|
|
|
|
|
|
|
Note: Drive skews specified for the signal in the interface specification also apply to async drives. If you need to drive the signal precisely when the drive is issued, do not specify any skew for that signal in the interface specification. |
|
|
|
|
|
Example : Async Signal Operation
|
|
|
|
|
|
1 #include "vera_defines.vrh"
2
3 // This is what connects with HDL
4 interface mem_if {
5 input clock CLOCK;
6 output [7:0] addr PHOLD #1;
7 input [7:0] rdata NSAMPLE #-1;
8 output [7:0] wdata NHOLD #1;
9 output wr NHOLD #1;
10 output rd NHOLD #1;
11 }
12
13 // Top level program
14 program async_signal {
15 bit [7:0] data = 0;
16 integer i;
17 mem_if.wr = 0;
18 mem_if.rd = 0;
19 repeat(10) @ (posedge mem_if.clock);
20 for (i=0; i < 10; i++) {
21 delay(1);
22 mem_if.addr = i async;
23 data = random() + 10;
24 mem_if.wdata = data async;
25 mem_if.wr = 1 async;
26 printf("%0dns Writing address %0x, with data %0x\n",get_time(LOW), i,data);
27 delay(1);
28 mem_if.wr = 0 async;
29 }
30 @ (CLOCK);
31 for (i=0; i < 10; i++) {
32 delay(1);
33 mem_if.addr = i async;
34 mem_if.rd = 1 async;
35 mem_if.wr = 0 async;
36 delay(1);
37 data = mem_if.rdata async;
38 printf("%0dns Reading address %0x",get_time(LOW),i);
39 printf(", data %0x\n",data);
40 mem_if.rd = 0 async;
41 }
42 }
You could download file async_signal.vr here
|
|
|
|
|
|
Verilog |
|
|
1 module async_signal_verilog ();
2 // Internal variables
3 reg clk;
4 reg [7:0] mem [0:255];
5 wire [7:0] rdata;
6
7 wire [7:0] addr;
8 wire [7:0] wdata;
9 wire wr,rd;
10
11 assign rdata = (rd) ? mem[addr] : 8'b0;
12
13 always @ (addr or wr or wdata)
14 if (wr) mem[addr] = wdata;
15
16 // Connect the program here
17 async_signal vshell(
18 .SystemClock (clk),
19 .\mem_if.clock (clk),
20 .\mem_if.addr (addr),
21 .\mem_if.rdata (rdata),
22 .\mem_if.wdata (wdata),
23 .\mem_if.wr (wr),
24 .\mem_if.rd (rd)
25 );
26 // Init all the variables
27 initial begin
28 clk = 0;
29 end
30 // Clock generator
31 always #1 clk = ~clk;
32
33 endmodule
You could download file async_signal.v here
|
|
|
|
|
|
Simulation : Async Signal Operation
|
|
|
|
|
|
20ns Writing address 0, with data b6
22ns Writing address 1, with data 27
24ns Writing address 2, with data c9
26ns Writing address 3, with data d3
28ns Writing address 4, with data 67
30ns Writing address 5, with data 74
32ns Writing address 6, with data 50
34ns Writing address 7, with data 4d
36ns Writing address 8, with data 69
38ns Writing address 9, with data 1f
41ns Reading address 0, data 0
43ns Reading address 1, data b6
45ns Reading address 2, data 27
47ns Reading address 3, data c9
49ns Reading address 4, data d3
51ns Reading address 5, data 67
53ns Reading address 6, data 74
55ns Reading address 7, data 50
57ns Reading address 8, data 4d
59ns Reading address 9, data 69
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|