STRUCTURAL MODELING
结构编程,bottom-up
3个2:1multiplexer组成4:1multiplexer
module mux4(input logic [3:0] d0, d1, d2, d3,
input logic [1:0] s,
output logic [3:0] y);
logic [3:0] low, high;
mux2 lowmux(d0, d1, s[0], low)
mux2 highmux(d2, d3, s[0], high)
mux2 finalmux(low, high, s[1], y)
endmodule
三态门组成multiplexer
module mux2(input logic [3:0] d0, d1,
input logic s,
output tri [3:0] y);
tristate t0(d0, ~s, y);
tristate t1(d1, s, y);
endmodule
SEQUENTIAL LOGIC
Registers
module flop(input logic clk,
input logic [3:0] d,
output logic [3:0] q);
always_ff @(posedge clk)
q <= d;
endmodule
//句式
always @(sensitivity list)
statement;
always statements can be used to imply flip-flops, latches, or combinational logic, depending on the sensitivity list and statement.
带reset的register
module flopr(input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q);
// asynchronous reset
always_ff @(posedge clk, posedge reset)
//4'b0 4bits 0000
if (reset) q <= 4'b0;
else q <= d;
endmodule
module flopr(input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q);
// synchronous reset
always_ff @(posedge clk)
if (reset) q <= 4'b0;
else q <= d;
endmodule
asynchronous的reset在sensitivity list
Multiple Registers
module sync(input logic clk,
input logic d,
output logic q);
logic n1;
always_ff @(posedge clk)
begin
n1 <= d; // nonblocking
q <= n1; // nonblocking
end
endmodule
begin和end在always的statement多条语句使用
Case Statements
module sevenseg(input logic [3:0] data,
output logic [6:0] segments);
always_comb
case(data)
// abc_defg
0: segments = 7'b111_1110;
1: segments = 7'b011_0000;
2: segments = 7'b110_1101;
3: segments = 7'b111_1001;
4: segments = 7'b011_0011;
5: segments = 7'b101_1011;
6: segments = 7'b101_1111;
7: segments = 7'b111_0000;
8: segments = 7'b111_1111;
9: segments = 7'b111_0011;
default: segments = 7'b000_0000;
endcase
endmodule
//In SystemVerilog, case statements must appear inside
//always statements.
If Statements
In SystemVerilog, if statements must appear inside of always statements.
FINITE STATE MACHINES
module divideby3FSM(input logic clk,
input logic reset,
output logic y);
typedef enum logic [1:0] {S0,S1,S2} statetype;
statetype [1:0] state, nextstate;
always_ff@(posedge clk, posedge reset)
if(reset) state <= S0;
else state <= nextstate;
always_comb
case(state)
S0: nextstate <= S1;
S1: nextstate <= S2;
S2: nextstate <= S0;
default: nextstate <= S0;
endcase
// output logic
assign y = (state == S0);
endmodule
//不同的typedef方式,指明状态编码
//typedef enum logic [2:0] {S0 = 3'b001, S1 = 3'b010, S2 = 3'b100} statetype;
module testbench3();
logic clk, reset;
logic a, b, c, y, yexpected;
logic [31:0] vectornum, errors;
logic [3:0] testvectors[10000:0];
// instantiate device under test
sillyfunction dut(a, b, c, y);
// generate clock
always
begin
clk = 1; #5; clk = 0; #5;
end
// at start of test, load vectors
// and pulse reset
initial
begin
$readmemb("example.tv", testvectors);
vectornum = 0; errors = 0;
reset = 1; #27; reset = 0;
end
// apply test vectors on rising edge of clk
always @(posedge clk)
begin
#1; {a, b, c, yexpected} = testvectors[vectornum];
end
// check results on falling edge of clk
always @(negedge clk)
if (~reset) begin // skip during reset
if (y !== yexpected) begin // check result
$display("Error: inputs = %b", {a, b, c});
$display(" outputs = %b (%b expected)", y, yexpected);
errors = errors + 1;
end
vectornum = vectornum + 1;
if (testvectors[vectornum] === 4'bx) begin
$display("%d tests completed with %d errors",
vectornum, errors);
$finish;
end
end
endmodule
if (testvectors[vectornum] === 4’bx) begin
$display(“%d tests completed with %d errors”,
vectornum, errors);
$finish;
end
end
endmodule