Digital Design and Computer Architecture 第四章归纳

0 前言

1
2
3
补充:
做完了教程平台里前三章的题,发现logisim里的多输入异或门和教材里描述的行为有差异。
教材里的多输入异或门起到奇偶校验的作用,而logisim里有单独的odd/even gates。

这章学习硬件描述语言,因为课程要求就只看Verilog的部分了。

突如其来的脑洞:

cover

1 概念

Module

A block of hardware with inputs and outputs is called a module.

Simulation and Synthesis

During simulation, inputs are applied to a module, and the outputs are checked to verify that the module operates correctly. During synthesis, the textual description of a module is transformed into logic gates.

2 Examples & Idioms

In our experience, the best way to learn an HDL is by example. HDLs have specific ways of describing various classes of logic; these ways are called idioms.

Combinational Logic

sillyfunction

1
2
3
4
5
6
module sillyfunction(input logic a,b,c
output logic y);
assign y=~a&~b&~c|
a&~b&~c|
a&~b& c;
endmodule

Bitwise Operators

Inverters

1
2
3
4
module inv(input logic [3:0] a,
output logic [3:0] y);
assign y=~a;
endmodule

Logic Gates

1
2
3
4
5
6
7
8
module gates(input logic [3:0] a, b,
output logic [3:0] y1, y2, y3, y4, y5);
assign y1=a&b;//AND
assign y2=a|b;//OR
assign y3=a^b;//XOR
assign y4=~(a&b);//NAND
assign y5=~(a|b);//NOR
endmodule

Reduction Operators

Eight-Input AND

1
2
3
4
module and8(input logic [7:0] a,
output logic y);
assign y=&a;
endmodule

Conditional Assignment

2:1 Multiplexer

1
2
3
4
5
module mux2(input logic [3:0] d0, d1,
input logic s,
output logic [3:0] y);
assign y= s?d1:d0;
endmodule

4:1 Multiplexer

1
2
3
4
5
module mux4(input logic [3:0] d0,d1,d2,d3,
input logic [1:0] s,
output logic [3:0] y);
assign y=s[1]?(s[0]?d3:d2):(s[0]?d1:d0);
endmodule

Internal Variables

Full Adder

1
2
3
4
5
6
7
8
module fulladder(input logic a, b, cin,
output logic s, cout);
logic p, g;
assign p=a^b;
assign g=a&b;
assign s=p^cin;
assign cout=g|(p&cin);
endmodule

Z’s and X’s

Tristate Buffers

Tristate busses can have multiple drivers, so they should be declared as a net. Two types of nets in SystemVerilog are called tri and trireg.

1
2
3
4
5
module tristate(input logic [3:0] a.
input logic en,
output tri [3:0] y);
assign y=en?a:4'bz;
endmodule

Bit Swizzling

1
assign y={c[2:1],{3{d[0]}},c[0],3'b101}

Delays

Logic Gates with Delays

1
2
3
4
5
6
7
8
9
10
'timescale 1ns/1ps
module example(input logic a,b,c,
output logic y);
logic ab,bb,cb,n1,n2,n3;
assign #1 {ab,bb,cb}=~{a,b,c};
assign #2 n1=ab&bb&cb;
assign #2 n2=a&bb&cb;
assign #2 n3=a&bb&c;
assign #4 y=n1|n2|n3;
endmodule

Structural Modeling

Structural Model of 4:1 Multiplexers

1
2
3
4
5
6
7
8
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

Accessing Parts of Busses

1
2
3
4
5
6
module mux2_8(input logic [7:0] d0, d1.
input logic s,
output logic [7:0] y);
mux2 lsbmux(d0[3:0], d1[3:0], s, y[3:0]);
mux2 msbmux(d0[7:4], d1[7:4], s, y[7:4]);
endmodule

Sequential Logic

Register

1
2
3
4
5
6
module flop(input logic clk,
input logic [3:0] d,
output logic [3:0] q);
always_ff @(posedge clk)
q<=d;
endmodule

Resettable Register

1. Asynchronous

1
2
3
4
5
6
7
8
module flopr(input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q);
always_ff @(posedge clk, posedge reset)
if(reset) q<=4'b0;
else q<=d;
endmodule

2. Synchronous

1
2
3
4
5
6
7
8
module flopr(input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q);
always_ff @(posedge clk)
if(reset) q<=4'b0;
else q<=d;
endmodule

Enabled Register

1
2
3
4
5
6
7
8
9
module flopr(input logic clk,
input logic reset,
input logic en,
input logic [3:0] d,
output logic [3:0] q);
always_ff @(posedge clk, posedge reset)
if(reset) q<=4'b0;
else if(en) q<=d;
endmodule

Synchronizer

1
2
3
4
5
6
7
8
9
10
module sync(input clk,
input logic d,
output logic q);
logic n1;
always_ff@(posedge clk)
begin
n1<=d;
q<=n1;
end
endmodule

More

D Latch

1
2
3
4
5
6
module latch(input logic clk,
input logic [3:0] d,
output logic [3:0] q);
always_latch
if (clk) q<=d;
endmodule

Inverter Using always

1
2
3
4
5
module inv(input logic [3:0] a,
output logic [3:0] y);
always_comb
y=~a;
endmodule

Full Adder Using always

1
2
3
4
5
6
7
8
9
10
11
module fulladder(input logic a, b, cin,
output logic s, cout);
logic p, g;
always_comb
begin
p=a^b;
g=a&b;
s=p^cin;
cout=g|(p&cin);
end
endmodule

Seven-Segment Display Decoder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

3:8 Decoder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module decoder3_8(input logic [2:0] a,
output logic [7:0] y);
always_comb
case(a)
3'b000: y = 8'b00000001;
3'b001: y = 8'b00000010;
3'b010: y = 8'b00000100;
3'b011: y = 8'b00001000;
3'b100: y = 8'b00010000;
3'b101: y = 8'b00100000;
3'b110: y = 8'b01000000;
3'b111: y = 8'b10000000;
default: y = 8'bxxxxxxxx;
endcase
endmodule

Priority Circuit

1
2
3
4
5
6
7
8
9
module priorityckt(input logic [3:0] a,
output logic [3:0] y);
always_comb
if(a[3]) y <= 4'b1000;
else if (a[2]) y <= 4'b0100;
else if (a[1]) y <= 4'b0010;
else if (a[0]) y <= 4'b0001;
else y <= 4'b0000;
endmodule

Priority Circuit Using Don’t Cares

1
2
3
4
5
6
7
8
9
10
11
module priority_casez(input logic [3:0] a,
output logic [3:0] y);
always_comb
casez(a)
4'b1???: y <= 4'b1000;
4'b01??: y <= 4'b0100;
4'b001?: y <= 4'b0010;
4'b0001: y <= 4'b0001;
default: y <= 4'b0000;
endcase
endmodule

Finite State Machines

Divide-By-3 Finite State Machines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
// state register
always_ff @(posedge clk, posedge reset)
if(reset) state<=S0;
else state<=nextstate;
//next state logic
always_comb
case(state)
S0: nextstate<=S1;
S1: nextstate<=S2;
S2: nextstate<=S0;
default :nextstate<=S0;
endcase
//output logic
assign y=(state == S0);
endmodule

Pattern Recognizer Moore FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module patternMoore(input logic clk,
input logic reset,
input logic a,
output logic y);
typedef enum logic[1:0]{S0,S1,S2} statetype;
statetype state, nextstate;
//state register
always_ff @(posedge clk,posedge reset)
if(reset) state <=S0;
else state<=nextstate;
//next state logic
always_comb
case(state)
S0:if(a) nextstate=S0;
else nextstate=S1;
S1:if(a) nextstate=S2;
else nextstate=S1;
S2: if (a) nextstate = S0;
else nextstate = S1;
default: nextstate = S0;
endcase
// output logic
assign y = (state == S2);
endmodule

Pattern Recognizer Mealy FSM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module patternMoore(input logic clk,
input logic reset,
input logic a,
output logic y);
typedef enum logic{S0,S1} statetype;
statetype state, nextstate;
//state register
always_ff @(posedge clk,posedge reset)
if(reset) state <=S0;
else state<=nextstate;
//next state logic
always_comb
case(state)
S0: if(a)nextstate=S0;
else nextstate=S1;
S1: if(a)nextstate=S0;
else nextstate=S1;
default: nextstate=S0;
endcase
assign y=(a & state==S1);
endmodule

Parameterized Modules

Parameterized N-Bit 2:1 Multiplexers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module mux2
#(parameter width=8)
(input logic[width-1:0]d0,d1,
input logic s,
output logic[width-1:0] y);
assign y=s?d1:d0;
endmodule

module mux4_12(input logic [11:0] d0,d1,d2,d2,
input logic [1:0] s,
output logic [11:0] y);
logic [11:0] low,hi;
mux2 #(12) lowmux(d0,d1,s[0],low);
mux2 #(12) himux(d2,d3,s[0],hi);
mux2 #(12) outmux(low,hi,s[1],y);
endmodule

Parameterized N-Input AND Gate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module andN
#(parameter width=8)
(input logic [width-1:0]a,
output logic y);
genvar i;
logic [width-1:0] x;
generate
assign x[0]=a[0];
for (i=1;i<width;i=i+1)begin: forloop
assign x[i]=a[i]&x[i-1];
end
endgenerate
assign y=x[width-1];
endmodule

Testbenches

累了,懒得手打了。

testbench1

testbench2

testbench3

3 准则

  1. Use always_ff @(posedge clk) and nonblocking assignments to model synchronous sequential logic.
  2. Use continuous assignments to model simple combinational logic.
  3. Use always_comb and blocking assignments to model more complicated combinational logic where the always statement is helpful.
  4. Do not make assignments to the same signal in more than one always statement or continuous assignment statement.

4 语法查阅

运算符优先级表

precedence

常数

The format for declaring constants is N’Bvalue, where N is the size in bits, B is a letter indicating the base, and value gives the value.

An exception is that ‘0 and ‘1 are SystemVerilog idioms for filling a bus with all 0s and all 1s, respectively.

Numbers

作者

Doxel

发布于

2022-08-11

更新于

2022-08-11

许可协议

评论