`timescale 1ns/1ns
module counter;
reg clock; // declare reg data type for the clock
integer count; // declare integer data type for the count
initial // initialize things - this executes once at start
begin
clock = 0; count = 0; // initialize signals
#340 ; // finish after 340 time ticks
end
/* an always statement to generate the clock, only one statement
follows the always so we don't need a begin and an end */
always
#10 clock = ~ clock; // delay is set to half the clock cycle
/* an always statement to do the counting, runs at the same time
(concurrently) as the other always statement */
always
begin
// wait here until the clock goes from 1 to 0
@ (negedge clock);
// now handle the counting
if (count == 7)
count = 0;
else
count = count + 1;
("time = ",," count = ", count);
end
endmodule
module identifiers;
/* multi-line comments in Verilog
look like C comments and // is OK in here */
// single-line comment in Verilog
reg legal_identifier,two__underscores;
reg _OK,OK_,OK_$,OK_123,CASE_SENSITIVE, case_sensitive;
reg \/clock ,\a*b ; // white_space after escaped identifier
//reg ,123_BAD; // bad names even if we declare them!
initial begin
legal_identifier =0; // embedded underscores are OK
two__underscores =0; // even two underscores in a row
_OK = 0; // identifiers can start with underscore
OK_ = 0; // and end with underscore
OK$ = 0; // $ sign is OK: beware foreign keyboards
OK_123 =0; // embedded digits are OK
CASE_SENSITIVE =0; // Verilog is case-sensitive
case_sensitive =1;
\/clock =0; // escaped identifier with \ breaks rules
\a*b =0; // but be careful! watch the spaces
("Variable CASE_SENSITIVE= %d",CASE_SENSITIVE);
("Variable case_sensitive= %d",case_sensitive);
("Variable \/clock = %d",\/clock );
("Variable \a*b = %d",\a*b );
end
endmodule
module declarations_1;
wire pwr_good,pwr_on,pwr_stable; // Explicitly declare wires
integer i; // 32-bit, signed (2's complement)
time t; // 64-bit, unsigned, behaves like a 64-bit reg
event e; // Declare an event data type
real r; // Real data type of implementation defined size
// assign statement continuously drives a wire...
assign pwr_stable = 1'b1; assign pwr_on = 1; // 1 or 1'b1
assign pwr_good = pwr_on & pwr_stable;
initial begin
i = 123.456; // There must be a digit on either side
r = 123456e-3; // of the decimal point if it is present.
t = 123456e-3; // Time is rounded to 1 second by default.
("i=%0g",i," t=%6.2f",t," r=%f",r);
#2 ("TIME=%0d",," ON=",pwr_on,
" STABLE=",pwr_stable," GOOD=",pwr_good);
; end
endmodule
module declarations_2;
reg Q, Clk; wire D;
// drive the wire (D)
assign D = 1;
// at +ve clock edge assign the value of wire D to the reg Q:
always @(posedge Clk) Q = D;
initial Clk = 0; always #10 Clk = ~ Clk;
initial begin #50; ; end
always begin
("T=%2g", ," D=",D," Clk=",Clk," Q=",Q); #10; end
endmodule
module declarations_3;
reg a,b,c,d,e;
initial begin
#10; a=0;b=0;c=0;d=0; #10; a=0;b=1;c=1;d=0;
#10; a=0;b=0;c=1;d=1; #10; ;
end
always begin
@(a or b or c or d) e = (a|b)&(c|d);
("T=%0g",," e=",e);
end
endmodule
module declarations_4;
wire Data; // a scalar net of type wire
wire [31:0] ABus, DBus; // two 32-bit wide vector wires...
// DBus[31] = left-most = most-significant bit = msb
// DBus[0] = right-most = least-significant bit = lsb
// Notice the size declaration precedes the names
// wire [31:0] TheBus, [15:0] BigBus; // illegal
reg [3:0] vector; // a 4-bit vector register
reg [4:7] nibble; // msb index < lsb index
integer i;
initial begin
i = 1;
vector = 'b1010; // vector without an index
nibble = vector; // this is OK too
#1; ("T=%0g",," vector=", vector," nibble=", nibble);
#2; ("T=%0g",," Bus=%b",DBus[15:0]);
end
assign DBus [1] = 1; // this is a bit-select
assign DBus [3:0] = 'b1111; // this is a part-select
// assign DBus [0:3] = 'b1111; // illegal - wrong direction
endmodule
module declarations_5;
reg [31:0] VideoRam [7:0]; // a 8-word by 32-bit wide memory
initial begin
VideoRam[1] = 'bxz; // must specify an index for a memory
VideoRam[2] = 1;
VideoRam[7] = VideoRam[VideoRam[2]]; // need 2 clock cycles for this
VideoRam[8] = 1; // careful! the compiler won't complain!
// Verify what we entered:
("VideoRam[0] is %b",VideoRam[0]);
("VideoRam[1] is %b",VideoRam[1]);
("VideoRam[2] is %b",VideoRam[2]);
("VideoRam[7] is %b",VideoRam[7]);
end
endmodule
module declarations_6;
integer Number [1:100]; // Notice that size follows name
time Time_Log [1:1000]; // - as in array of reg
// real Illegal [1:10]; // ***no real arrays***
endmodule
module constants;
parameter H12_UNSIZED = 'h 12; // unsized hex 12 = decimal 18
parameter H12_SIZED = 6'h 12; // sized hex 12 = decimal 18
// Notice that a space between base and value is OK
/* '' (single apostrophes) are not the same as the ' character */
parameter D42 = 8'B0010_1010; // bin 101010 = dec 42
// ...we can use underscores to increase readability.
parameter D123 = 123; // unsized decimal (default)
parameter D63 = 8'o 77; // sized octal, decimal 63
// parameter ILLEGAL = 1'o9; // no 9's in octal numbers!
/* A = 'hx and B = 'ox assume a 32 bit width */
parameter A = 'h x, B = 'o x, C = 8'b x, D = 'h z, E = 16'h ????;
// ...we can use ? instead of z, same as E = 16'h zzzz
// ...note automatic extension to 16 bits
reg [3:0] B0011,Bxxx1,Bzzz1; real R1,R2,R3; integer I1,I3,I_3;
parameter BXZ = 8'b1x0x1z0z;
initial begin
B0011 = 4'b11; Bxxx1 = 4'bx1; Bzzz1 = 4'bz1; // left padded
R1 = 0.1e1; R2 = 2.0; R3 = 30E-01; // real numbers
I1 = 1.1; I3 = 2.5; I_3 = -2.5; // IEEE rounds away from 0
end
initial begin #1;
("H12_UNSIZED, H12_SIZED (hex) = %h, %h",H12_UNSIZED, H12_SIZED);
("D42 (bin) = %b",D42," (dec) = %d",D42);
("D123 (hex) = %h",D123," (dec) = %d",D123);
("D63 (oct) = %o",D63);
("A (hex) = %h",A," B (hex) = %h",B);
("C (hex) = %h",C," D (hex) = %h",D," E (hex) = %h",E);
("BXZ (bin) = %b",BXZ," (hex) = %h",BXZ);
("B0011, Bxxx1, Bzzz1 (bin) = %b, %b, %b",B0011,Bxxx1,Bzzz1);
("R1, R2, R3 (e, f, g) = %e, %f, %g", R1, R2, R3);
("I1, I3, I_3 (d) = %d, %d, %d", I1, I3, I_3);
end
endmodule
module negative_numbers;
parameter PA = -12, PB = -'d12, PC = -32'd12, PD = -4'd12;
integer IA , IB , IC , ID ; reg [31:0] RA , RB , RC , RD ;
initial begin #1;
IA = -12; IB = -'d12; IC = -32'd12; ID = -4'd12;
RA = -12; RB = -'d12; RC = -32'd12; RD = -4'd12; #1;
(" parameter integer reg[31:0]");
("-12 =",PA,IA,,,RA);
(" ",,,,PA,,,,IA,,,,,RA);
("-'d12 =",,PB,IB,,,RB);
(" ",,,,PB,,,,IB,,,,,RB);
("-32'd12 =",,PC,IC,,,RC);
(" ",,,,PC,,,,IC,,,,,RC);
("-4'd12 =",,,,,,,,,,PD,ID,,,RD);
(" ",,,,,,,,,,,PD,,,,ID,,,,,RD);
end
endmodule
module characters; /*
" is ASCII 34 (hex 22), double quote
' is ASCII 39 (hex 27), tick or apostrophe
/ is ASCII 47 (hex 2F), forward slash
\ is ASCII 92 (hex 5C), back slash
` is ASCII 96 (hex 60), accent grave
| is ASCII 124 (hex 7C), vertical bar
no standards for the graphic symbols for codes above 128...
´ is 171 (hex AB), accent acute in almost all fonts
" is 210 (hex D2), open double quote, like 66 (some fonts)
" is 211 (hex D3), close double quote, like 99 (some fonts)
' is 212 (hex D4), open single quote, like 6 (some fonts)
' is 213 (hex D5), close single quote, like 9 (some fonts)
*/ endmodule
module text;
parameter A_String = "abc"; // string constant, must be on one line
parameter Say = "Say \"Hey!\"";
// use escape quote \" for an embedded quote
parameter Tab = " "; // tab character
parameter NewLine = "
"; // newline character
parameter BackSlash = "\"; // back slash
parameter Tick = "'"; // ASCII code for tick in octal
// parameter Illegal = "@"; // illegal - no such ASCII code
initial begin
("A_String(str) = %s ",A_String," (hex) = %h ",A_String);
("Say = %s ",Say," Say \"Hey!\"");
("NewLine(str) = %s ",NewLine," (hex) = %h ",NewLine);
\ Following changed in 3rd printing to clarify use of backslash
\ ("\(str) = %s ",BackSlash," (hex) = %h ",BackSlash);
("\(str) = %s ",BackSlash," (hex) = %h ",BackSlash);
("Tab(str) = %s ",Tab," (hex) = %h ",Tab,"1 newline...");
("
");
("Tick(str) = %s ",Tick," (hex) = %h ",Tick);
#1.23; ("Time is %t", );
end
endmodule
module define;
`define G_BUSWIDTH 32 // bus width parameter (G_ for global)
/* Note: there is no semicolon at end of a compiler directive. The
character ` is ASCII 96 (hex 60), accent grave, it slopes down from
left to right. It is not the tick or apostrophe character ' (ASCII 39
or hex 27)*/
wire [`G_BUSWIDTH:0]MyBus; // 32-bit bus
endmodule
module operators;
parameter A10xz = {1'b1,1'b0,1'bx,1'bz}; // concatenation
parameter A01010101 = {4{2'b01}}; // replication
// arithmetic operators: +, -, *, /, and modulus %
parameter A1 = (3+2) %2; // result of % takes sign of argument #1
// logical shift operators: << (left), >> (right)
parameter A2 = 4 >> 1; parameter A4 = 1 << 2; // zero fill
// relational operators: <, <=, >, >=
initial if (1 > 2) ;
// logical operators: ! (negation), && (and), || (or)
parameter B0 = !12; parameter B1 = 1 && 2;
reg [2:0] A00x; initial begin A00x = 'b111; A00x = !2'bx1; end
parameter C1 = 1 || (1/0); /* this may or may not cause an
error: the short-circuit behavior of && and || is undefined. An
evaluation including && or || may stop when an expression is known
to be true or false */
// == (logical equality), != (logical inequality)
parameter Ax = (1==1'bx); parameter Bx = (1'bx!=1'bz);
parameter D0 = (1==0); parameter D1 = (1==1);
// === case equality, !== (case inequality)
// case operators only return true or false
parameter E0 = (1===1'bx); parameter E1 = 4'b01xz === 4'b01xz;
parameter F1 = (4'bxxxx === 4'bxxxx);
// bitwise logical:
// ~ (negation), & (and), | (inclusive or),
// ^ (exclusive or), ~^ or ^~ (equivalence)
parameter A00 = 2'b01 & 2'b10;
// unary logical reduction:
// & (and), ~& (nand), | (or), ~| (nor),
// ^ (xor), ~^ or ^~ (xnor)
parameter G1= & 4'b1111;
// conditional expression x = a ? b : c
// if (a) then x = b else x = c
reg H0, a, b, c; initial begin a=1; b=0; c=1; H0=a?b:c; end
reg[2:0] J01x, Jxxx, J01z, J011;
initial begin Jxxx = 3'bxxx; J01z = 3'b01z; J011 = 3'b011;
J01x = Jxxx ? J01z : J011; end // bitwise result
initial begin #1;
("A10xz=%b",A10xz," A01010101=%b",A01010101);
("A1=%0d",A1," A2=%0d",A2," A4=%0d",A4);
("B1=%b",B1," B0=%b",B0," A00x=%b",A00x);
("C1=%b",C1," Ax=%b",Ax," Bx=%b",Bx);
("D0=%b",D0," D1=%b",D1);
("E0=%b",E0," E1=%b",E1," F1=%b",F1);
("A00=%b",A00," G1=%b",G1," H0=%b",H0);
("J01x=%b",J01x); end
endmodule
module modulo; reg [2:0] Seven;
initial begin
#1 Seven = 7; #1 ("Before=", Seven);
#1 Seven = Seven + 1; #1 ("After =", Seven);
end
endmodule
Before=7
After =0
module LRM_arithmetic;
integer IA, IB, IC, ID, IE; reg [15:0] RA, RB, RC;
initial begin
IA = -4'd12; RA = IA / 3;
RB = -4'd12; IB = RB / 3;
IC = -4'd12 / 3; RC = -12 / 3;
ID = -12 / 3; IE = IA / 3;
end
initial begin #1;
(" hex default");
("IA = -4'd12 = %h%d",IA,IA);
("RA = IA / 3 = %h %d",RA,RA);
("RB = -4'd12 = %h %d",RB,RB);
("IB = RB / 3 = %h%d",IB,IB);
("IC = -4'd12 / 3 = %h%d",IC,IC);
("RC = -12 / 3 = %h %d",RC,RC);
("ID = -12 / 3 = %h%d",ID,ID);
("IE = IA / 3 = %h%d",IE,IE);
end
endmodule
module holiday_1(sat, sun, weekend);
input sat, sun; output weekend;
assign weekend = sat | sun;
endmodule
`timescale 100s/1s // units are 100 seconds with precision of 1s
module life; wire [3:0] n; integer days;
wire wake_7am, wake_8am; // wake at 7 on weekdays else at 8
assign n = 1 + (days % 7); // n is day of the week (1-6)
always@(wake_8am or wake_7am)
("Day=",n," hours=%0d ",(/36)%24," 8am = ",
wake_8am," 7am = ",wake_7am," m2.weekday = ", m2.weekday);
initial days = 0;
initial begin #(24*36*10);; end // run for 10 days
always #(24*36) days = days + 1; // bump day every 24hrs
rest m1(n, wake_8am); // module instantiation
// creates a copy of module rest with instance name m1
// ports are linked using positional notation
work m2(.weekday(wake_7am), .day(n));
// creates a copy of module work with instance name m2
// ports are linked using named association
endmodule
module rest(day, weekend); // module definition
// notice the port names are different from parent
input [3:0] day; output weekend; reg weekend;
always begin #36 weekend = day > 5; end // need delay
endmodule
module work(day, weekday);
input [3:0] day; output weekday; reg weekday;
always begin #36 weekday = day < 6; end // need delay
endmodule
module holiday_1(sat, sun, weekend);
input sat, sun; output weekend;
assign weekend = sat | sun; // outside a procedure
endmodule
module holiday_2(sat, sun, weekend);
input sat, sun; output weekend; reg weekend;
always #1 weekend = sat | sun; // inside a procedure
endmodule
module assignment_1();
wire pwr_good,pwr_on,pwr_stable; reg Ok,Fire;
assign pwr_stable = Ok&(!Fire);
assign pwr_on = 1;
assign pwr_good = pwr_on & pwr_stable;
initial begin Ok=0;Fire=0; #1 Ok=1; #5 Fire=1;end
initial begin ("TIME=%0d",," ON=",pwr_on, " STABLE=",
pwr_stable," OK=",Ok," FIRE=",Fire," GOOD=",pwr_good);
#10 ; end
endmodule
module assignment_2; reg Enable; wire [31:0] Data;
/* the following single statement is equivalent to a declaration and
continuous assignment */
wire [31:0] DataBus = Enable ? Data : 32'bz;
assign Data = 32'b10101101101011101111000010100001;
initial begin
("Enable=%b DataBus=%b ", Enable, DataBus);
Enable = 0; #1; Enable = 1; #1; end
endmodule
module always_1; reg Y, Clk;
always // statements in an always statement execute repeatedly...
begin: my_block // start of sequential block
@(posedge Clk) #5 Y = 1; // at +ve edge set Y=1
@(posedge Clk) #5 Y = 0; // at the NEXT +ve edge set Y=0
end // end of sequential block
always #10 Clk = ~ Clk; // ...we need a clock
initial Y = 0; // these initial statements execute
initial Clk = 0; // only once, but first...
initial ("T=%2g",," Clk=",Clk," Y=",Y);
initial #70 ;
endmodule
module procedural_assign; reg Y, A;
always @(A)
Y = A; // procedural assignment
initial begin A=0; #5; A=1; #5; A=0; #5; ; end
initial ("T=%2g",,,"A=",A,,,"Y=",Y);
endmodule
module delay_controls; reg X,Y,Clk,Dummy;
always #1 Dummy=!Dummy; // dummy clock, just for graphics
// examples of delay controls...
always begin #25 X=1;#10 X=0;#5; end
// an event control:
always @(posedge Clk) Y=X; // wait for +ve clock edge
always #10 Clk = !Clk; // the real clock
initial begin Clk = 0;
("T Clk X Y");
("%2g",,,,Clk,,,,X,,Y);
;#100 ; end
endmodule
module show_event;
reg clock;
event event_1, event_2; // declare two named events
always @(posedge clock) -> event_1; // trigger event_1
always @ event_1
begin ("Strike 1!!"); -> event_2; end // trigger event_2
always @ event_2 begin ("Strike 2!!");
; end // stop on detection of event_2
always #10 clock = ~ clock; // we need a clock
initial clock = 0;
endmodule
module data_slip_1 (); reg Clk,D,Q1,Q2;
/************* bad sequential logic below ***************/
always @(posedge Clk) Q1 = D;
always @(posedge Clk) Q2 = Q1; // data slips here!
/************* bad sequential logic above ***************/
initial begin Clk=0; D=1; end always #50 Clk=~Clk;
initial begin ("t Clk D Q1 Q2");
("%3g",,,Clk,,,,D,,Q1,,,Q2); end
initial #400 ; // run for 8 cycles
initial ;
endmodule
module test_dff_wait;
reg D,Clock,Reset; dff_wait u1(D,Q,Clock,Reset);
initial begin D=1;Clock=0;Reset=1'b1;#15 Reset=1'b0;#20 D=0;end
always #10 Clock=!Clock;
initial begin ("T Clk D Q Reset");
("%2g",,,Clock,,,,D,,Q,,Reset); #50 ; end
endmodule
module dff_wait(D,Q,Clock,Reset);
output Q; input D,Clock,Reset; reg Q; wire D;
always @(posedge Clock) if (Reset!==1) Q=D;
always begin wait (Reset==1) Q=0; wait (Reset!==1); end
endmodule
module dff_wait(D,Q,Clock,Reset);
output Q; input D,Clock,Reset; reg Q; wire D;
always @(posedge Clock) if (Reset!==1) Q=D;
// we need another wait statement here or we shall spin forever
always begin wait (Reset==1) Q=0; end
endmodule
module delay;
reg a,b,c,d,e,f,g,bds,bsd;
initial begin
a = 1; b = 0; // no delay
#1 b = 1; // delayed assignment
c = #1 1; // intra-assignment delay
#1; //
d = 1; //
e <= #1 1; // intra-assignment, non-blocking
#1 f <= 1; // delayed non-blocking
g <= 1; // non-blocking
end
initial begin #1 bds = b; end // delay then sample (ds)
initial begin bsd = #1 b; end // sample then delay (sd)
initial begin ("t a b c d e f g bds bsd");
("%g",,,a,,b,,c,,d,,e,,f,,g,,bds,,,,bsd); end
endmodule
module dff_procedural_assign;
reg d,clr_,pre_,clk; wire q; dff_clr_pre dff_1(q,d,clr_,pre_,clk);
always #10 clk = ~clk;
initial begin clk = 0; clr_ = 1; pre_ = 1; d = 1;
#20; d = 0; #20; pre_ = 0; #20; pre_ = 1; #20; clr_ = 0;
#20; clr_ = 1; #20; d = 1; #20; ; end
initial begin
("T CLK PRE_ CLR_ D Q");
("%3g",,,,clk,,,,pre_,,,,clr_,,,,d,,q); end
endmodule
module dff_clr_pre(q,d,clear_,preset_,clock);
output q; input d,clear_,preset_,clock; reg q;
always @(clear_ or preset_)
if (!clear_) assign q = 0; // active low clear
else if(!preset_) assign q = 1; // active low preset
else deassign q;
always @(posedge clock) q = d;
endmodule
module F_subset_decode; reg [2:0]A,B,C,D,E,F;
initial begin A=1;B=0;D=2;E=3;
C=subset_decode(A,B); F=subset_decode(D,E);
("A B C D E F");(A,,B,,C,,D,,E,,F); end
function [2:0] subset_decode; input [2:0] a,b;
begin if (a<=b) subset_decode=a; else subset_decode=b; end
endfunction
endmodule
module test_mux; reg a,b,select; wire out;
mux mux_1(a,b,out,select);
initial begin #2; select = 0; a = 0; b = 1;
#2; select = 1'bx; #2; select = 1'bz; #2; select = 1; end
initial ("T=%2g",," Select=",select," Out=",out);
initial #10 ;
endmodule
module mux(a, b, mux_output, mux_select); input a, b, mux_select;
output mux_output; reg mux_output;
always begin
case(mux_select)
0: mux_output = a;
1: mux_output = b;
default mux_output = 1'bx; // if select = x or z set output to x
endcase
#1; // need some delay, otherwise we'll spin forever
end
endmodule
module loop_1;
integer i; reg [31:0] DataBus; initial DataBus = 0;
initial begin
/************** insert loop code after here ******************/
/* for(execute this <assignment> once before starting loop;
exit loop if this <expression> is false; execute this <
assignment> at end of loop before the check for end of loop) */
for(i=0; i<=15; i=i+1) DataBus[i]=1;
/*************** insert loop code before here ****************/
end
initial begin
("DataBus = %b",DataBus);
#2; ("DataBus = %b",DataBus); ;
end
endmodule
module fork
event a,b;
initial
fork
@eat_breakfast; @read_paper;
join
end
endmodule
module primitive;
nand (strong0, strong1) #2.2
Nand_1(n001, n004, n005),
Nand_2(n003, n001, n005, n002);
nand (n006, n005, n002);
endmodule
primitive Adder(Sum, InA, InB);
output Sum; input Ina, InB;
table
// inputs : output
00 : 0;
01 : 1;
10 : 1;
11 : 0;
endtable
endprimitive
primitive DLatch(Q, Clock, Data);
output Q; reg Q; input Clock, Data;
table
//inputs : present state : output (next state)
1 0 : ? : 0; // ? represents 0,1, or x input
1 1 : b : 1; // b represents 0 or 1 input
1 1 : x : 1; // could have combined this with previous line
// The following line is as it appeared in printing 1 and 2.
// 0 1 : ? : -; // - represents no change in an output
// Changed as follows by Mike Smith, 10/11/97, for printing 3.
0 ? : ? : -; // - represents no change in an output
//
// Explanation: I had never intended that this example to be
// a complete and correct model of a latch, it was meant only
// to illustrate UDP truth-table declaration. However, the
// problem with the original code (a missing truth-table
// specification for the case Clock=0 and Data equal to anything
// other than 1) looks like an error. It could cause confusion
// if someone was either (a) trying to figure out how this
// state-dependent UDP modeled a latch or (b) just blindly
// copied the code from the book text and used it.
// So, I have changed it.
//
endtable
endprimitive
primitive DFlipFlop(Q, Clock, Data);
output Q; reg Q; input Clock, Data;
table
//inputs : present state : output (next state)
r 0 : ? : 0 ; // rising edge, next state = output = 0
r 1 : ? : 1 ; // rising edge, next state = output = 1
(0x) 0 : 0 : 0 ; // rising edge, next state = output = 0
(0x) 1 : 1 : 1 ; // rising edge, next state = output = 1
(?0) ? : ? : - ; // falling edge, no change in output
? (??) : ? : - ; // no clock edge, no change in output
endtable
endprimitive
module DFF_Spec; reg D, clk;
DFF_Part DFF1 (Q, clk, D, pre, clr);
initial begin D = 0; clk = 0; #1; clk = 1; end
initial ("T=%2g",," clk=",clk," Q=",Q);
endmodule
module DFF_Part(Q, clk, D, pre, clr);
input clk, D, pre, clr; output Q;
DFlipFlop(Q, clk, D); // no preset or clear in this UDP
specify
specparam
tPLH_clk_Q = 3, tPHL_clk_Q = 2.9,
tPLH_set_Q = 1.2, tPHL_set_Q = 1.1;
(clk => Q) = (tPLH_clk_Q, tPHL_clk_Q);
(pre, clr *> Q) = (tPLH_set_Q, tPHL_set_Q);
endspecify
endmodule
`timescale 1 ns / 100 fs
module M_Spec; reg A1, A2, B; M M1 (Z, A1, A2, B);
initial begin A1=0;A2=1;B=1;#5;B=0;#5;A1=1;A2=0;B=1;#5;B=0;end
initial
("T=%4g",," A1=",A1," A2=",A2," B=",B," Z=",Z);
endmodule
`timescale 100 ps / 10 fs
module M(Z, A1, A2, B); input A1, A2, B; output Z;
or (Z1, A1, A2); nand (Z, Z1, B); // OAI21
/*A1 A2 B Z delay=10*100 ps unless shown below...
0 0 0 1
0 0 1 1
0 1 0 1 B:0->1 Z:1->0 delay=t2
0 1 1 0 B:1->0 Z:0->1 delay=t1
1 0 0 1 B:0->1 Z:1->0 delay=t4
1 0 1 0 B:1->0 Z:0->1 delay=t3
1 1 0 1
1 1 1 0 */
specify specparam t1=11,t2=12; specparam t3=13,t4=14;
(A1 => Z) = 10; (A2 => Z) = 10;
if (~A1) (B => Z) = (t1, t2); if (A1) (B => Z) = (t3, t4);
endspecify
endmodule
module Vector_And(Z,A,B);
parameter CARDINALITY = 1;
input [CARDINALITY-1:0] A,B;
output [CARDINALITY-1:0] Z;
wire [CARDINALITY-1:0] Z = A & B;
endmodule
module Four_And_Gates(OutBus, InBusA, InBusB);
input [3:0] InBusA, InBusB; output [3:0] OutBus;
Vector_And #(4) My_AND(OutBus, InBusA, InBusB); // 4 AND gates
endmodule
module And_Gates(OutBus, InBusA, InBusB);
parameter WIDTH = 1;
input [WIDTH-1:0] InBusA, InBusB; output [WIDTH-1:0] OutBus;
Vector_And #(WIDTH) My_And(OutBus, InBusA, InBusB);
endmodule
module Super_Size; defparam And_Gates.WIDTH = 4; endmodule
/******************************************************/
/* module viterbi_encode */
/******************************************************/
/* This is the encoder. X2N (msb) and X1N form the 2-bit input
message, XN. Example: if X2N=1, X1N=0, then XN=2. Y2N (msb), Y1N, and
Y0N form the 3-bit encoded signal, YN (for a total constellation of 8
PSK signals that will be transmitted). The encoder uses a state
machine with four states to generate the 3-bit output, YN, from the
2-bit input, XN. Example: the repeated input sequence XN = (X2N, X1N)
= 0, 1, 2, 3 produces the repeated output sequence YN = (Y2N, Y1N,
Y0N) = 1, 0, 5, 4. */
module viterbi_encode(X2N,X1N,Y2N,Y1N,Y0N,clk,res);
input X2N,X1N,clk,res; output Y2N,Y1N,Y0N;
wire X1N_1,X1N_2,Y2N,Y1N,Y0N;
dff dff_1(X1N,X1N_1,clk,res); dff dff_2(X1N_1,X1N_2,clk,res);
assign Y2N=X2N; assign Y1N=X1N ^ X1N_2; assign Y0N=X1N_1;
endmodule
/******************************************************/
/* module viterbi_distances */
/******************************************************/
/* This module simulates the front-end of a receiver. Normally the
received analog signal (with noise) is converted into a series of
distance measures from the known eight possible transmitted PSK
signals: s1,...s7. We are not simulating the analog part or noise in
this version so we just take the digitally encoded 3-bit signal, Y,
from the encoder and convert it directly to the distance measures.
d[N] is the distance from signal=N to signal=0
d[N] = (2*sin(N*PI/8))**2 in 3-bit binary (on the scale 2=100)
Example: d[3] = 1.85**2 = 3.41 = 110
inN is the distance from signal=N to encoder signal.
Example: in3 is the distance from signal=3 to encoder signal.
d[N] is the distance from signal=N to encoder signal=0.
If encoder signal=J, shift the distances by 8-J positions.
Example: if signal=2, in0 is d[6], in1 is D[7], in2 is D[0], etc. */
module viterbi_distances
(Y2N,Y1N,Y0N,clk,res,in0,in1,in2,in3,in4,in5,in6,in7);
input clk,res,Y2N,Y1N,Y0N; output in0,in1,in2,in3,in4,in5,in6,in7;
reg [2:0] J,in0,in1,in2,in3,in4,in5,in6,in7; reg [2:0] d [7:0];
initial begin d[0]='b000;d[1]='b001;d[2]='b100;d[3]='b110;
d[4]='b111;d[5]='b110;d[6]='b100;d[7]='b001; end
always @(Y2N or Y1N or Y0N) begin
J[0]=Y0N;J[1]=Y1N;J[2]=Y2N;
J=8-J;in0=d[J];J=J+1;in1=d[J];J=J+1;in2=d[J];J=J+1;in3=d[J];
J=J+1;in4=d[J];J=J+1;in5=d[J];J=J+1;in6=d[J];J=J+1;in7=d[J];
end endmodule
/*****************************************************/
/* module viterbi_test_CDD */
/*****************************************************/
/* This is the top level module, viterbi_test_CDD, that models the
communications link. It contains three modules: viterbi_encode,
viterbi_distances, and viterbi. There is no analog and no noise in
this version. The 2-bit message, X, is encoded to a 3-bit signal, Y.
In this module the message X is generated using a simple counter.
The digital 3-bit signal Y is transmitted, received with noise as an
analog signal (not modeled here), and converted to a set of eight
3-bit distance measures, in0, ..., in7. The distance measures form
the input to the Viterbi decoder that reconstructs the transmitted
signal Y, with an error signal if the measures are inconsistent.
CDD = counter input, digital transmission, digital reception */
module viterbi_test_CDD;
wire Error; // decoder out
wire [2:0] Y,Out; // encoder out, decoder out
reg [1:0] X; // encoder inputs
reg Clk, Res; // clock and reset
wire [2:0] in0,in1,in2,in3,in4,in5,in6,in7;
always #500 ("t Clk X Y Out Error");
initial ("%4g",,,Clk,,,,X,,Y,,Out,,,,Error);
initial ; initial #3000 ;
always #50 Clk=~Clk; initial begin Clk=0;
X=3; // no special reason to start at 3
#60 Res=1;#10 Res=0;end // hit reset after inputs are stable
always @(posedge Clk) #1 X=X+1; // drive input with counter
viterbi_encode v_1
(X[1],X[0],Y[2],Y[1],Y[0],Clk,Res);
viterbi_distances v_2
(Y[2],Y[1],Y[0],Clk,Res,in0,in1,in2,in3,in4,in5,in6,in7);
viterbi v_3
(in0,in1,in2,in3,in4,in5,in6,in7,Out,Clk,Res,Error);
endmodule
/******************************************************/
/* module dff */
/******************************************************/
/* A D flip-flop module. */
module dff(D,Q,Clock,Reset); // N.B. reset is active-low
output Q; input D,Clock,Reset;
parameter CARDINALITY = 1; reg [CARDINALITY-1:0] Q;
wire [CARDINALITY-1:0] D;
always @(posedge Clock) if (Reset!==0) #1 Q=D;
always begin wait (Reset==0); Q=0; wait (Reset==1); end
endmodule
/* Verilog code for a Viterbi decoder. The decoder assumes a rate
2/3 encoder, 8 PSK modulation, and trellis coding. The viterbi module
contains eight submodules: subset_decode, metric, compute_metric,
compare_select, reduce, pathin, path_memory, and output_decision.
The decoder accepts eight 3-bit measures of ||r-si||**2 and, after
an initial delay of twelve clock cycles, the output is the best
estimate of the signal transmitted. The distance measures are the
Euclidean distances between the received signal r (with noise) and
each of the (in this case eight) possible transmitted signals s0-s7.
Original by Christeen Gray, University of Hawaii. Heavily modified
by MJSS, any errors are mine. Use freely. */
/******************************************************/
/* module viterbi */
/******************************************************/
/* This is the top level of the Viterbi decoder. The eight input
signals {in0,...,in7} represent the distance measures, ||r-si||**2.
The other input signals are clk and reset. The output signals are
out and error. */
module viterbi
(in0,in1,in2,in3,in4,in5,in6,in7,
out,clk,reset,error);
input [2:0] in0,in1,in2,in3,in4,in5,in6,in7;
output [2:0] out; input clk,reset; output error;
wire sout0,sout1,sout2,sout3;
wire [2:0] s0,s1,s2,s3;
wire [4:0] m_in0,m_in1,m_in2,m_in3;
wire [4:0] m_out0,m_out1,m_out2,m_out3;
wire [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
wire ACS0,ACS1,ACS2,ACS3;
wire [4:0] out0,out1,out2,out3;
wire [1:0] control;
wire [2:0] p0,p1,p2,p3;
wire [11:0] path0;
subset_decode u1(in0,in1,in2,in3,in4,in5,in6,in7,
s0,s1,s2,s3,sout0,sout1,sout2,sout3,clk,reset);
metric u2(m_in0,m_in1,m_in2,m_in3,m_out0,
m_out1,m_out2,m_out3,clk,reset);
compute_metric u3(m_out0,m_out1,m_out2,m_out3,s0,s1,s2,s3,
p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,error);
compare_select u4(p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
out0,out1,out2,out3,ACS0,ACS1,ACS2,ACS3);
reduce u5(out0,out1,out2,out3,
m_in0,m_in1,m_in2,m_in3,control);
pathin u6(sout0,sout1,sout2,sout3,
ACS0,ACS1,ACS2,ACS3,path0,clk,reset);
path_memory u7(p0,p1,p2,p3,path0,clk,reset,
ACS0,ACS1,ACS2,ACS3);
output_decision u8(p0,p1,p2,p3,control,out);
endmodule
/******************************************************/
/* module subset_decode */
/******************************************************/
/* This module chooses the signal corresponding to the smallest of
each set {||r-s0||**2,||r-s4||**2}, {||r-s1||**2, ||r-s5||**2},
{||r-s2||**2,||r-s6||**2}, {||r-s3||**2,||r-s7||**2}. Therefore
there are eight input signals and four output signals for the
distance measures. The signals sout0, ..., sout3 are used to control
the path memory. The statement dff #(3) instantiates a vector array
of 3 D flip-flops. */
module subset_decode
(in0,in1,in2,in3,in4,in5,in6,in7,
s0,s1,s2,s3,
sout0,sout1,sout2,sout3,
clk,reset);
input [2:0] in0,in1,in2,in3,in4,in5,in6,in7;
output [2:0] s0,s1,s2,s3;
output sout0,sout1,sout2,sout3;
input clk,reset;
wire [2:0] sub0,sub1,sub2,sub3,sub4,sub5,sub6,sub7;
dff #(3) subout0(in0, sub0, clk, reset);
dff #(3) subout1(in1, sub1, clk, reset);
dff #(3) subout2(in2, sub2, clk, reset);
dff #(3) subout3(in3, sub3, clk, reset);
dff #(3) subout4(in4, sub4, clk, reset);
dff #(3) subout5(in5, sub5, clk, reset);
dff #(3) subout6(in6, sub6, clk, reset);
dff #(3) subout7(in7, sub7, clk, reset);
function [2:0] subset_decode; input [2:0] a,b;
begin
subset_decode = 0;
if (a<=b) subset_decode = a; else subset_decode = b;
end
endfunction
function set_control; input [2:0] a,b;
begin
if (a<=b) set_control = 0; else set_control = 1;
end
endfunction
assign s0 = subset_decode (sub0,sub4);
assign s1 = subset_decode (sub1,sub5);
assign s2 = subset_decode (sub2,sub6);
assign s3 = subset_decode (sub3,sub7);
assign sout0 = set_control(sub0,sub4);
assign sout1 = set_control(sub1,sub5);
assign sout2 = set_control(sub2,sub6);
assign sout3 = set_control(sub3,sub7);
endmodule
/******************************************************/
/* module compute_metric */
/******************************************************/
/* This module computes the sum of path memory and the distance for
each path entering a state of the trellis. For the four states,
there are two paths entering it, therefore eight sums are computed
in this module. The path metrics and output sums are 5-bits wide.
The output sum is bounded and should never be greater than 5-bits
for a valid input signal. The overflow from the sum is the error
output and indicates an invalid input signal.*/
module compute_metric
(m_out0,m_out1,m_out2,m_out3,
s0,s1,s2,s3,p0_0,p2_0,
p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
error);
input [4:0] m_out0,m_out1,m_out2,m_out3;
input [2:0] s0,s1,s2,s3;
output [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
output error;
assign
p0_0 = m_out0 + s0,
p2_0 = m_out2 + s2,
p0_1 = m_out0 + s2,
p2_1 = m_out2 + s0,
p1_2 = m_out1 + s1,
p3_2 = m_out3 + s3,
p1_3 = m_out1 + s3,
p3_3 = m_out3 + s1;
function is_error; input x1,x2,x3,x4,x5,x6,x7,x8;
begin
if (x1||x2||x3||x4||x5||x6||x7||x8) is_error = 1;
else is_error = 0;
end
endfunction
assign error = is_error(p0_0[4],p2_0[4],p0_1[4],p2_1[4],
p1_2[4],p3_2[4],p1_3[4],p3_3[4]);
endmodule
/******************************************************/
/* module compare_select */
/******************************************************/
/* This module compares the summations from the compute_metric
module and selects the metric and path with the lowest value. The
output of this module is saved as the new path metric for each
state. The ACS output signals are used to control the path memory of
the decoder. */
module compare_select
(p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
out0,out1,out2,out3,
ACS0,ACS1,ACS2,ACS3);
input [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
output [4:0] out0,out1,out2,out3;
output ACS0,ACS1,ACS2,ACS3;
function [4:0] find_min_metric; input [4:0] a,b;
begin
if (a<=b) find_min_metric=a; else find_min_metric=b;
end
endfunction
function set_control; input [4:0] a,b;
begin
if (a<=b) set_control=0; else set_control=1;
end
endfunction
assign out0=find_min_metric(p0_0,p2_0);
assign out1=find_min_metric(p0_1,p2_1);
assign out2=find_min_metric(p1_2,p3_2);
assign out3=find_min_metric(p1_3,p3_3);
assign ACS0 = set_control (p0_0,p2_0);
assign ACS1 = set_control (p0_1,p2_1);
assign ACS2 = set_control (p1_2,p3_2);
assign ACS3 = set_control (p1_3,p3_3);
endmodule
/******************************************************/
/* module path */
/******************************************************/
/* This is the basic unit for the path memory of the Viterbi
decoder. It consists of four 3-bit D flip-flops in parallel. There
is a 2:1 mux at each D flip-flop input. The statement dff #(12)
instantiates a vector array of 12 flip-flops. */
module path(in,out,clk,reset,ACS0,ACS1,ACS2,ACS3);
input [11:0] in; output [11:0] out;
input clk,reset,ACS0,ACS1,ACS2,ACS3; wire [11:0] p_in;
dff #(12) path0(p_in,out,clk,reset);
function [2:0] shift_path; input [2:0] a,b; input control;
begin
if (control == 0) shift_path = a; else shift_path = b;
end
endfunction
assign p_in[11:9]=shift_path(in[11:9],in[5:3],ACS0);
assign p_in[ 8:6]=shift_path(in[11:9],in[5:3],ACS1);
assign p_in[ 5:3]=shift_path(in[8: 6],in[2:0],ACS2);
assign p_in[ 2:0]=shift_path(in[8: 6],in[2:0],ACS3);
endmodule
/******************************************************/
/* module path_memory */
/******************************************************/
/* This module consists of an array of memory elements (D
flip-flops) that store and shift the path memory as new signals are
added to the four paths (or four most likely sequences of signals).
This module instantiates 11 instances of the path module. */
module path_memory
(p0,p1,p2,p3,
path0,clk,reset,
ACS0,ACS1,ACS2,ACS3);
output [2:0] p0,p1,p2,p3; input [11:0] path0;
input clk,reset,ACS0,ACS1,ACS2,ACS3;
wire [11:0]out1,out2,out3,out4,out5,out6,out7,out8,out9,out10,out11;
path x1 (path0,out1 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x2 (out1, out2 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x3 (out2, out3 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x4 (out3, out4 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x5 (out4, out5 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x6 (out5, out6 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x7 (out6, out7 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x8 (out7, out8 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x9 (out8, out9 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x10(out9, out10,clk,reset,ACS0,ACS1,ACS2,ACS3),
x11(out10,out11,clk,reset,ACS0,ACS1,ACS2,ACS3);
assign p0=out11[11:9];
assign p1=out11[ 8:6];
assign p2=out11[ 5:3];
assign p3=out11[ 2:0];
endmodule
/******************************************************/
/* module pathin */
/******************************************************/
/* This module determines the input signal to the path for each of
the four paths. Control signals from the subset decoder and compare
select modules are used to store the correct signal. The statement
dff #(12) instantiates a vector array of 12 flip-flops. */
module pathin
(sout0,sout1,sout2,sout3,
ACS0,ACS1,ACS2,ACS3,
path0,clk,reset);
input sout0,sout1,sout2,sout3,ACS0,ACS1,ACS2,ACS3;
input clk,reset; output [11:0] path0;
wire [2:0] sig0,sig1,sig2,sig3; wire [11:0] path_in;
dff #(12) firstpath(path_in,path0,clk,reset);
function [2:0] subset0; input sout0;
begin
if(sout0 == 0) subset0 = 0; else subset0 = 4;
end
endfunction
function [2:0] subset1; input sout1;
begin
if(sout1 == 0) subset1 = 1; else subset1 = 5;
end
endfunction
function [2:0] subset2; input sout2;
begin
if(sout2 == 0) subset2 = 2; else subset2 = 6;
end
endfunction
function [2:0] subset3; input sout3;
begin
if(sout3 == 0) subset3 = 3; else subset3 = 7;
end
endfunction
function [2:0] find_path; input [2:0] a,b; input control;
begin
if(control==0) find_path = a; else find_path = b;
end
endfunction
assign sig0 = subset0(sout0);
assign sig1 = subset1(sout1);
assign sig2 = subset2(sout2);
assign sig3 = subset3(sout3);
assign path_in[11:9] = find_path(sig0,sig2,ACS0);
assign path_in[ 8:6] = find_path(sig2,sig0,ACS1);
assign path_in[ 5:3] = find_path(sig1,sig3,ACS2);
assign path_in[ 2:0] = find_path(sig3,sig1,ACS3);
endmodule
/******************************************************/
/* module metric */
/******************************************************/
/* The registers created in this module (using D flip-flops) store
the four path metrics. Each register is 5 bits wide. The statement
dff #(5) instantiates a vector array of 5 flip-flops. */
module metric
(m_in0,m_in1,m_in2,m_in3,
m_out0,m_out1,m_out2,m_out3,
clk,reset);
input [4:0] m_in0,m_in1,m_in2,m_in3;
output [4:0] m_out0,m_out1,m_out2,m_out3;
input clk,reset;
dff #(5) metric3(m_in3, m_out3, clk, reset);
dff #(5) metric2(m_in2, m_out2, clk, reset);
dff #(5) metric1(m_in1, m_out1, clk, reset);
dff #(5) metric0(m_in0, m_out0, clk, reset);
endmodule
/******************************************************/
/* module output_decision */
/******************************************************/
/* This module decides the output signal based on the path that
corresponds to the smallest metric. The control signal comes from
the reduce module. */
module output_decision(p0,p1,p2,p3,control,out);
input [2:0] p0,p1,p2,p3; input [1:0] control; output [2:0] out;
function [2:0] decide;
input [2:0] p0,p1,p2,p3; input [1:0] control;
begin
if(control == 0) decide = p0;
else if(control == 1) decide = p1;
else if(control == 2) decide = p2;
else decide = p3;
end
endfunction
assign out = decide(p0,p1,p2,p3,control);
endmodule
/******************************************************/
/* module reduce */
/******************************************************/
/* This module reduces the metrics after the addition and compare
operations. This algorithm selects the smallest metric and subtracts
it from the other three metrics. */
module reduce
(in0,in1,in2,in3,
m_in0,m_in1,m_in2,m_in3,
control);
input [4:0] in0,in1,in2,in3;
output [4:0] m_in0,m_in1,m_in2,m_in3;
output [1:0] control; wire [4:0] smallest;
function [4:0] find_smallest;
input [4:0] in0,in1,in2,in3; reg [4:0] a,b;
begin
if(in0<=in1) a=in0; else a=in1;
if(in2<=in3) b=in2; else b=in3;
if(a<=b) find_smallest = a;
else find_smallest = b;
end
endfunction
function [1:0] smallest_no;
input [4:0] in0,in1,in2,in3,smallest;
begin
if(smallest == in0) smallest_no = 0;
else if (smallest == in1) smallest_no = 1;
else if (smallest == in2) smallest_no = 2;
else smallest_no = 3;
end
endfunction
assign smallest = find_smallest(in0,in1,in2,in3);
assign m_in0 = in0 - smallest;
assign m_in1 = in1 - smallest;
assign m_in2 = in2 - smallest;
assign m_in3 = in3 - smallest;
assign control = smallest_no(in0,in1,in2,in3,smallest);
endmodule
module test_display; // display system tasks...
initial begin ("string, variables, or expression");
/* format specifications work like printf in C...
%d=decimal %b=binary %s=string %h=hex %o=octal
%c=character %m=hierarchical name %v=strength %t=time format
%e=scientific %f=decimal %g=shortest
examples: %d uses default width %0d uses minimum width
%7.3g uses 7 spaces with 3 digits after decimal point */
// , , print in b, h, o formats
// , , also have b, h, o versions
("write"); // as , but without newline at end of line
("strobe"); // as , values at end of simulation cycle
(v); // disp. @change of v (except v= ,,)
; ; // toggle monitor mode on/off
end endmodule
module file_1; integer f1, ch; initial begin f1 = ("f1.out");
if(f1==0) (2); if(f1==2)("f1 open");
ch = f1|1; (ch,"Hello"); (f1); end endmodule
module load; reg [7:0] mem[0:7]; integer i; initial begin
("mem.dat", mem, 1, 6); // start_address=1, end_address=6
for (i= 0; i<8; i=i+1) ("mem[%0d] %b", i, mem[i]);
end endmodule
// timescale tasks...
module a; initial (b.c1); endmodule
module b; c c1 (); endmodule
`timescale 10 ns / 1 fs
module c_dat; endmodule
`timescale 1 ms / 1 ns
module Ttime; initial (-9, 5, " ns", 10); endmodule
/* [ ( n, p, suffix , min_field_width ) ] ;
units = 1 second ** (-n), n=0->15, e.g. for n=9, units = ns
p = digits after decimal point for %t e.g. p=5 gives 0.00000
suffix for %t (despite timescale directive)
min_field_width is number of character positions for %t */
module test_simulation_control; // simulation control system tasks...
initial begin ; // enter interactive mode (default parameter 1)
(2); // graceful exit with optional parameter as follows...
// 0=nothing 1=time and location 2=time, location, and statistics
end endmodule
module timing_checks (data, clock, clock_1,clock_2);
input data,clock,clock_1,clock_2;reg tSU,tH,tHIGH,tP,tSK,tR;
specify // timing check system tasks...
/* (data_event, reference_event, limit [, notifier]);
violation = (T_reference_event)-(T_data_event) < limit */
(data, posedge clock, tSU);
/* (reference_event, data_event, limit [, notifier]);
violation =
(time_of_data_event)-(time_of_reference_event) < limit */
(posedge clock, data, tH);
/* (reference_event, data_event, setup_limit,
hold_limit [, notifier]);
parameter_restriction = setup_limit + hold_limit > 0 */
(posedge clock, data, tSU, tH);
/* (reference_event, limit, threshold [, notifier]);
violation =
threshold < (T_data_event) - (T_reference_event) < limit
reference_event = edge
data_event = opposite_edge_of_reference_event */
(posedge clock, tHIGH);
/* (reference_event, limit [, notifier]);
violation = (T_data_event) - (T_reference_event) < limit
reference_event = edge
data_event = same_edge_of_reference event */
(posedge clock, tP);
/* (reference_event, data_event, limit [, notifier]);
violation = (T_data_event) - (T_reference_event) > limit */
(posedge clock_1, posedge clock_2, tSK);
/* (reference_event, data_event, limit, [, notifier]);
violation = (T_data_event) - (T_reference_event) < limit */
(posedge clock, posedge clock_2, tR);
/* (reference_event, data_event, start_edge_offset,
end_edge_offset [, notifier]);
reference_event = posedge | negedge
violation = change while reference high (posedge)/low (negedge)
+ve start_edge_offset moves start of window later
+ve end_edge_offset moves end of window later */
(posedge clock, data, 0, 0);
endspecify endmodule
primitive dff_udp(q, clock, data, notifier);
output q; reg q; input clock, data, notifier;
table //clock data notifier:state:q
r 0 ? : ? :0 ;
r 1 ? : ? :1 ;
n ? ? : ? :- ;
? * ? : ? :- ;
? ? * : ? :x ; endtable // ...notifier
endprimitive
`timescale 100 fs / 1 fs
module dff(q, clock, data);output q; input clock, data; reg notifier;
dff_udp(q1, clock, data, notifier); buf(q, q1);
specify
specparam tSU = 5, tH = 1, tPW = 20, tPLH = 4:5:6, tPHL = 4:5:6;
(clock *> q) = (tPLH, tPHL);
(data, posedge clock, tSU, notifier); // setup: data to clock
(posedge clock, data, tH, notifier); // hold: clock to data
(posedge clock, tPW, notifier); // clock: period
endspecify
endmodule
module pla_1 (a1,a2,a3,a4,a5,a6,a7,b1,b2,b3);
input a1, a2, a3, a4, a5, a6, a7 ; output b1, b2, b3;
reg [1:7] mem[1:3]; reg b1, b2, b3;
initial begin
("array.dat", mem);
#1; b1=1; b2=1; b3=1;
(mem,{a1,a2,a3,a4,a5,a6,a7},{b1,b2,b3});
end
initial ("%4g",,,b1,,b2,,b3);
endmodule
module pla_2; reg [1:3] a, mem[1:4]; reg [1:4] b;
initial begin
(mem,{a[1],a[2],a[3]},{b[1],b[2],b[3],b[4]});
mem[1] = 3'b10?; mem[2] = 3'b??1; mem[3] = 3'b0?0; mem[4] = 3'b???;
#10 a = 3'b111; #10 (a, " -> ", b);
#10 a = 3'b000; #10 (a, " -> ", b);
#10 a = 3'bxxx; #10 (a, " -> ", b);
#10 a = 3'b101; #10 (a, " -> ", b);
end endmodule
module stochastic; initial begin // stochastic analysis system tasks...
/* (q_id, q_type, max_length, status) ;
q_id is an integer that uniquely identifies the queue
q_type 1=FIFO 2=LIFO
max_length is an integer defining the maximum number of entries */
(q_id, q_type, max_length, status) ;
/* (q_id, job_id, inform_id, status) ;
job_id=integer input
inform_id= user-defined integer input for queue entry */
(q_id, job_id, inform_id, status) ;
/* (q_id, job_id, inform_id, status) ; */
(q_id, job_id, inform_id, status) ;
/* (q_id, status) ;
status = 0 = queue is not full, status = 1 = queue full */
(q_id, status) ;
/* (q_id, q_stat_code, q_stat_value, status) ;
q_stat_code is input request as follows...
1=current queue length 2=mean inter-arrival time 3=max. queue length
4=shortest wait time ever
5=longest wait time for jobs still in queue 6=ave. wait time in queue
q_stat_value is output containing requested value */
(q_id, q_stat_code, q_stat_value, status) ;
end endmodule
module test_time;initial begin // simulation time system functions...
;
// returns 64-bit integer scaled to timescale unit of invoking module
;
// returns 32-bit integer scaled to timescale unit of invoking module
;
// returns real scaled to timescale unit of invoking module
end endmodule
module test_convert; // conversion functions for reals...
integer i; real r; reg [63:0] bits;
initial begin #1 r=256;#1 i = (r);
#1; r = (2*i) ; #1 bits = (2.0*r) ;
#1; r = (bits) ; end
initial ("%3f",,,i,,r,,bits); /*
converts reals to integers w/truncation e.g. 123.45 -> 123
converts integers to reals e.g. 123 -> 123.0
converts reals to 64-bit vector
converts bit pattern to real
...real numbers in these functions conform to IEEE 754. Conversion
rounds to the nearest valid number. */
endmodule
module test_real;wire [63:0]a;driver d (a);receiver r (a);
initial ("%3g",,,a,,d.r1,,r.r2); endmodule
module driver (real_net);
output real_net; real r1; wire [64:1] real_net = (r1);
initial #1 r1 = 123.456; endmodule
module receiver (real_net);
input real_net; wire [64:1] real_net; real r2;
initial assign r2 = (real_net);
endmodule
module probability; // probability distribution functions...
/* [ ( seed ) ] returns random 32-bit signed integer
seed = register, integer, or time */
reg [23:0] r1,r2; integer r3,r4,r5,r6,r7,r8,r9;
integer seed, start, nd , mean, standard_deviation;
integer degree_of_freedom, k_stage;
initial begin seed=1; start=0; nd =6; mean=5;
standard_deviation=2; degree_of_freedom=2; k_stage=1; #1;
r1 = % 60; // random -59 to 59
r2 = % 60; // positive value 0-59
r3= (seed, start, nd ) ;
r4= (seed, mean, standard_deviation) ;
r5= (seed, mean) ;
r6= (seed, mean) ;
r7= (seed, degree_of_freedom) ;
r8= (seed, degree_of_freedom) ;
r9= (seed, k_stage, mean) ;end
initial #2 ("%3f",,,r1,,r2,,r3,,r4,,r5);
initial begin #3; ("%3f",,,r6,,r7,,r8,,r9); end
/* All parameters are integer values.
Each function returns a pseudo-random number
e.g. returns uniformly distributed random numbers
mean, degree_of_freedom, k_stage
(exponential, poisson, chi-square, t, erlang) > 0.
seed = inout integer initialized by user, updated by function
start, end () = integer bounding return values */
endmodule
Spell-checked by MJSS on
Last modified by MJSS on 01/02/98
|