Input and Output Skews
`timescale 1ns/1ns
// program declaration with ports.
program clocking_skew_prg (
input wire clk,
output logic [7:0] din,
input wire [7:0] dout,
output logic [7:0] addr,
output logic ce,
output logic we
);
// Clocking block
clocking ram @(posedge clk);
input #3 dout;
output #3 din,addr,ce,we;
endclocking
initial begin
// Init the outputs
ram.addr <= 0;
ram.din <= 0;
ram.ce <= 0;
ram.we <= 0;
// Write Operation to Ram
for (int i = 0; i < 2; i++) begin
@ (posedge clk);
ram.addr <= i;
ram.din <= $random;
ram.ce <= 1;
ram.we <= 1;
@ (posedge clk);
ram.ce <= 0;
end
// Read Operation to Ram
for (int i = 0; i < 2; i++) begin
@ (posedge clk);
ram.addr <= i;
ram.ce <= 1;
ram.we <= 0;
// Below line is same as @ (posedge clk);
@ (ram);
ram.ce <= 0;
end
#40 $finish;
end
endprogram
// Simple top level file
module clocking_skew();
logic clk = 0;
wire [7:0] din;
logic [7:0] dout;
wire [7:0] addr;
wire ce;
wire we;
reg [7:0] memory [0:255];
// Clock generator
always #10 clk++;
// Simple ram model
always @ (posedge clk)
if (ce)
if (we)
memory[addr] <= din;
else
dout <= memory[addr];
// Monitor all the signals
initial begin
$monitor("@%0dns addr :%0x din %0x dout %0x we %0x ce %0x",
$time, addr, din,dout,we,ce);
end
// Connect the program
clocking_skew_prg U_program(
.clk (clk),
.din (din),
.dout (dout),
.addr (addr),
.ce (ce),
.we (we)
);
endmodule
@0ns addr :xx din xx dout xx we x ce x
@11ns addr :0 din 24 dout xx we 1 ce 1
@31ns addr :0 din 24 dout xx we 1 ce 0
@51ns addr :1 din 81 dout xx we 1 ce 1
@71ns addr :1 din 81 dout xx we 1 ce 0
@91ns addr :0 din 81 dout xx we 0 ce 1
@110ns addr :0 din 81 dout 24 we 0 ce 1
@111ns addr :0 din 81 dout 24 we 0 ce 0
@131ns addr :1 din 81 dout 24 we 0 ce 1
@150ns addr :1 din 81 dout 81 we 0 ce 1
@151ns addr :1 din 81 dout 81 we 0 ce 0
从仿真上看,input延时了3个单位,但是output没有
Hierarchical Names
`timescale 1ns/1ns
// program declaration with ports.
program clocking_hier_prg (
input wire clk,
output logic [7:0] din,
input wire [7:0] dout,
output logic [7:0] addr,
output logic ce,
output logic we
);
// Clocking block
clocking ram @(posedge clk);
input #1 dout = clocking_skew.dout;
output #1 din,addr,ce,we;
endclocking
initial begin
$monitor("@%0dns addr :%0x din %0x dout %0x we %0x ce %0x",
$time, addr, din,ram.dout,we,ce);
// Init the outputs
ram.addr <= 0;
ram.din <= 0;
ram.ce <= 0;
ram.we <= 0;
// Write Operation to Ram
for (int i = 0; i < 2; i++) begin
@ (posedge clk);
ram.addr <= i;
ram.din <= $random;
ram.ce <= 1;
ram.we <= 1;
@ (posedge clk);
ram.ce <= 0;
end
// Read Operation to Ram
for (int i = 0; i < 2; i++) begin
@ (posedge clk);
ram.addr <= i;
ram.ce <= 1;
ram.we <= 0;
// Below line is same as @ (posedge clk);
@ (ram);
ram.ce <= 0;
end
#40;
end
endprogram
// Simple top level file
module clocking_skew();
logic clk = 0;
wire [7:0] din;
logic [7:0] dout;
wire [7:0] addr;
wire ce;
wire we;
reg [7:0] memory [0:255];
// Clock generator
always #10 clk++;
// Simple ram model
always @ (posedge clk)
if (ce)
if (we)
memory[addr] <= din;
else
dout <= memory[addr];
// Connect the program
clocking_hier_prg U_program(
.clk (clk),
.din (din),
.dout (),
.addr (addr),
.ce (ce),
.we (we)
);
endmodule
Cycle Delay
## n表示延时n个时钟周期
// Below line is same as repeat (2) @ (posedge clk);
## 2;
// Below line is same as @ (posedge clk);
## 1;
// Below line is same as repeat (3) @ (posedge clk);
## 3;
Default clock
module clocking_default();
logic clk = 0;
always #10 clk++;
// Specify the default clocking
default clocking test @ (posedge clk);
endclocking
initial begin
$display("%0dns is current time",$time);
// Any ## is evaluated with respect to default clock
##100;
$display("%0dns is current time",$time);
$finish;
end
endmodule