[关闭]
@byjr-k 2016-01-06T17:01:24.000000Z 字数 10047 阅读 2249

EEE339 Part 1

大学学习


Lecture 1

HDL (Hardware Description Language) is a computer language that is used to describe hardware.

Two main HDLs are used by industry:

Modules can be specified in two ways:

Structural Representation

and(y, x1, x2);
or(y, x1, x2, x3, x4);
not(y, x);

(y for output and x for input(s))

Behavioral Representation

  1. module example(x1, x2, x3, f);
  2. input x1, x2, x3;
  3. output f;
  4. assign f = (x1 & x2) | (~x2 & x3);
  5. endmodule
  1. module example(x1, x2, x3, f);
  2. input x1, x2, x3;
  3. output f;
  4. reg f;
  5. always @(x1, x2, x3)
  6. if (x2 == 1)
  7. f = x1;
  8. else
  9. f = x3;
  10. endmodule

Concurrent vs. Procedural Statements

Concurrent statements are considered in parallel and the ordering in the code does not matter. This includes gate instantiations and continuous assignment.
assign的出现顺序不影响

Procedural statements are evaluated in the order in which they appear in the code. This statements are required to be contained inside an always block.
always中的顺序与代码保持一致

Lecture 2

Lexical Conventions (词法约定)

Whitepsace Characters

空格,制表符,空行全都无视

Comments

与C语言一样,有两种,分别是单行注释和多行注释

多行注释的效果跟C#一样,可以写在一行代码的中间

Identifiers

用字母或者下划线开头
后面可以是字母、数字、下划线以及美元符号($)

Logic Values

Why x:

Why z:


For common logic gates:

除了AND只要有一个0就输出0,以及OR只要有一个1就输出1以外,只要input有x或z,就输出x(课件并没有指出如果有两个x、z或者x、z同时出现的output是什么)

还有一种叫不上名字的门电路,三角形,有两个输入A和S。如果S为1,则输出为A,否则为z。

Number

Radix Letter
decimal d or D
hexadecimal h or H
octal o or O
binary b or B

如果啥也不写,比如wire x = 15, 指的是32位十进制数

下划线(underscore)“_”被无视(用来增强可阅读性,如8'b0000_1010
如果size比数字大,则数字左边填充为0
如果数字最左边是z或x,则左边填充为z或x

Data Type Declarations

同种数据可以一次性声明多个,比如reg A, B, reg [3:0] X, Y
integer是32位reg

Lecture 3

Operators

Arithmetic Operators (算术运算符)

1 + 1
1 - 1
-1
3 * 2
5 / 3
6 % 3

如果%运算中有负数,则先按正数计算,然后添加负号

Bitwise Operators (按位运算符)

~m // not
m & n
m | n
m ^ n // Exclusive OR
m ~^ n
m ^~ n // Both are Exclusive NOR

Logical Operators (逻辑运算符)

!m
m && n
m || n

Reduction Operators (缩减运算符)

&m
~&m
|m
~|m
^m
~^m
^~m

从左往右(反之也可)逐位计算,结果为1 bit
偶数个1或0连续异或的结果是0,奇数个0或者1连续异或的结果为1

Example:

value & ~& | ~| ^ ~^
4'b0011 0 1 1 0 0 1

Relational Operators (关系运算符)

<
>
<=
>=
==
!=
===
!==

对于==(Equality Operators),只有当每一位的1或者0都相同,才能返回1。如果有x,则返回x
对于===(Identity Operators),如果每一位对应的内容相同(包括z和x),则返回1

Shift Operators (移位运算符)

m >> n
m << n
m <<< n
m >>> n

Conditional Operator (条件运算符)

? :

跟C语言一样,没啥好说的

Concatenation(串联) Operator & Replication(复制) Operator

{}

Example

A = 1'b1, B = 2'b00, C = 2'b10, D = 3'b110
Y = {B, C};
Y = {B[0], D[2], 2'b11};
Y = {B, D[2:0]};
Y = {4{A}, 2{B}, C};

Operator Precedence(运算符优先级)

Operator type Operator symbols Precedence
Complement ! ~ - Highest
Arithmetic
    / + -
Shift << >>
Relational < <= > >=
Equality == !=
Reduction & ~& ^ ~^ | ~|
Logical && ||
Conditional ?: Lowest

Lecture 4

Module defination

Items

Port Connections

Module Instantiations (模块实例化)

  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. assign {Cout, s} = x + y + Cin;
  5. endmodule
  6. module adder4(carryin, X, Y, S, carryout);
  7. input carryin;
  8. input [3:0] X, Y;
  9. output [3:0] S;
  10. output carryout;
  11. wire [3:1] C;
  12. // order
  13. fulladd stage0(carryin, X[0], Y[0], S[0], C[1]);
  14. // name
  15. fulladd stage3(.Cout(carrout), .s(S[3]), .y(X[3]), .x(X[3]), .Cin(C[3]));
  16. endmodule

Parameter Redefinition

  1. module bit_count(X, Count);
  2. parameter n = 4;
  3. parameter logn = 2;
  4. // ...
  5. endmodule
  6. module common(X, Y, C);
  7. input [7:0] X, Y;
  8. output [3:0] C;
  9. wire [7:0] T;
  10. // method 1
  11. bit_count cbits(T, C);
  12. defparam cbits.n = 8, cbits.logn = 3;
  13. // method 2
  14. bit_count #(8, 3) cbits(T, C);

Generate Construct

感觉就是用来弄好几个连续的module,比如fulladder

  1. // old method
  2. module adder4(carryin, X, Y, S, carryout);
  3. fulladd stage0(carryin, X[0], Y[0], S[0], C[1]);
  4. fulladd stage1(carryin, X[1], Y[1], S[1], C[2]);
  5. fulladd stage2(carryin, X[2], Y[2], S[2], C[3]);
  6. fulladd stage3(carryin, X[3], Y[3], S[3], carryout);
  7. endmodule
  8. // new method
  9. module adder4(carryin, X, Y, S, carryout);
  10. parameter n = 4;
  11. wire [n:0] C;
  12. genvar i;
  13. assign C[0] = carryin;
  14. assign carryout = C[n];
  15. generate
  16. for (i=0; i<=n-1; i=i+1)
  17. begin:addbit
  18. fulladd stage(C[i], X[i], Y[i], S[i], C[i+1]);
  19. end
  20. endgenerate
  21. endmodule

每一个instance的名称分别是addbit[i].stage

Lecture 5

Primitive Instantiations

借助大二所学知识,总能够将逻辑电路设计为借助基础逻辑门(AND, OR, NOT, XOR等)组成的电路

  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. assign {Cout, s} = x + y + Cin;
  5. endmodule
  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. wire z1, z2, z3, z4;
  5. and And1(z1, x, y);
  6. add And2(z2, x, Cin);
  7. add And3(z3, y, Cin);
  8. or Or1(Cout, z1, z2, z3);
  9. xor Xor1(z4, x, y);
  10. xor Xor2(s, z4, Cin);
  11. endmodule

下面的方法省略了原始实例的实例名称,以及涉及的wire的定义,也是可行的

  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. and(z1, x, y);
  5. add(z2, x, Cin);
  6. add(z3, y, Cin);
  7. or(Cout, z1, z2, z3);
  8. xor(z4, x, y);
  9. xor(s, z4, Cin);
  10. endmodule

gate_type [#(delay)] [instance_name] (input_port, ..., output_port, ...);
* gate_type 门电路的类型,所有可用的会在下面的表格中说明
* instance_name: optional
* #(delay): propagation delay in time units, optional

Gate Types

常见的逻辑门电路

and(f, a, b, ...)
nand(f, a, b, ...)
or(f, a, b, ...)
nor(f, a, b, ...)
xor(f, a, b, ...)
xnor(f, a, b, ...)
not(f, a)

特殊的门电路

buf(f, a) // f = a
notif0(f, a, e) // f = !e? ~a : 'bz
notif1(f, a, e) // f =  e? ~a : 'bz
bufif0(f, a, e) // f = !e?  a : 'bz
bufif1(f, a, e) // f =  e?  a : 'bz

'bz1'bz的省略,1 bit的高阻态
buffer的作用大概是在电路中起到缓冲作用。如果一部分电流过大,则不至于使整个电路受到牵连

Continuous Assignments

Explicit

  1. net_type [size] net_name;
  2. assign net_name = expression;
  3. // Example
  4. input x1, x2;
  5. output f;
  6. assign f = x1 & x2;

Implicit

  1. net_type [size] net_name = expression;
  2. // Example
  3. input x1, x2;
  4. output f = x1 & x2;

assign s = x ^ y, c = x & y;

wire s = x ^ y, c = x & y;

Procedural Statement

Procedural Statement必须出现在always或initial blocks中,或者在function或task中,而且只被内部的always或initial调用(后面这种东西压根没学过,也没见过)

D-type flip-flop

  1. module DFF(D, Clock, Q);
  2. input D, Clock;
  3. output Q;
  4. reg Q;
  5. always @(posedge Clock) begin
  6. Q = D;
  7. end
  8. endmodule

这个模块只检测clock的上升沿,不管D的状态有无改变,Q的值都只会在下一个clock上升沿进行赋值
always@后面括号中的内容为sensitivity list,可以为某个或某些信号的高低变化,或者上升沿、下降沿
括号中出现的内容只能是同种的信号,比如(s1 or s2 or s3),再比如(posedge c1 or negedge c2)
理论上,逗号和or可以互换,不过还是用or吧……

Procedural Assignment Statements

  1. initial begin
  2. Q1 = 1;
  3. Q2 = 0;
  4. end
  5. // 以下代码在一个时钟周期后,Q1和Q2都等于0
  6. always@(posedge clk) begin
  7. Q1 = Q2;
  8. Q2 = Q1;
  9. end
  10. // 以下代码在一个时钟周期后,Q1和Q2的值互换
  11. always@(posedge clk) begin
  12. Q1 <= Q2;
  13. Q2 <= Q1;
  14. end

Lecture 6

if else

没啥说的,完全可以理解为C语言的if用法,只不过把花括号换成begin end

case casex casez

  1. case (s)
  2. 0: f = 0;
  3. 1: f = 2;
  4. 2: f = 5;
  5. default: f = z; // optional
  6. endcase

don't care指的是,只比较其他的1或者0
alternative中如果语句超过一行,则也要使用begin end
以上的中文语法体系已经彻底崩坏……

for while

跟C语言没两样,除了花括号和begin end的区别
for中使用的递增数使用reg或integer类型

repeat forever

这俩并没用过,也没见过,更不知道forever有卵用(莫非像是单片机里面那样,出特殊情况就直接开始死循环?)

repeat (expression) statement;
forever statement;

repeat:重复expression次statement
forever:无限循环statement

Lecture 7

function

  1. // 4-to-1 multiplexer
  2. module mux16to1(W, S16, f);
  3. // ...
  4. function mux4to1;
  5. input [3:0] W;
  6. input [1:0] S;
  7. mux4to1 = W[S];
  8. endfunction
  9. // ...
  10. endmodule

此处开始,课件变得很迷,有时候是[3:0],有时候是[0:3]。这其实是MSB与LSB的区别,互相之间是左右颠倒的

task

  1. // 4-to-1 multiplexer
  2. module mux16to1(W, S16, f);
  3. // ...
  4. task mux4to1;
  5. input [3:0] W;
  6. input [1:0] S;
  7. output Result;
  8. begin
  9. Result = W[S];
  10. end
  11. endtask
  12. // ...
  13. endmodule

后面讲了multiplexer, decoder, encoder, comparator,感觉没啥卵用,就不写了

Lecture 9

莫名其妙的,并没有Lecture 8

本节主要讲了加法器,以及overflow(溢出)
然而看起来没啥用,所以在此复习一下以前的关于boolean的运算



异或符合结合律(associative rule)

2's complement

先按位取反,然后+1

 2 = 0010
     1101
-2 = 1110 (1101 + 1)
     0001
 2 = 0010 (0001 + 1)
  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. xor(s, x, y, Cin);
  5. and(z1, x, y);
  6. and(z2, x, Cin);
  7. and(z3, y, Cin);
  8. or(Cout, z1, z2, z3);
  9. endmodule
  1. module fulladd(Cin, x, y, s, Cout);
  2. input Cin, x, y;
  3. output s, Cout;
  4. assign s = x ^ y ^ Cin;
  5. assign Cout = (x & y) | (x & Cin) | (y & Cin);
  6. endmodule
  1. module adder4(carryin, X, Y, S, carryout);
  2. input carryin;
  3. input [3:0] X, Y;
  4. output [3:0] S;
  5. output carryout;
  6. wire [3:1] C;
  7. fulladd stage0(carryin, X[0], Y[0], S[0], C[1]);
  8. fulladd stage1(C[1], X[1], Y[1], S[1], C[2]);
  9. fulladd stage2(C[2], X[2], Y[2], S[2], C[3]);
  10. fulladd stage3(C[3], X[3], Y[3], S[3], carryout);
  11. endmodule
  1. module addern(carryin, X, Y, S, carryout);
  2. parameter n = 32;
  3. input carryin;
  4. input [n-1:0] X, Y;
  5. output reg [n-1:0] S;
  6. output reg carryout;
  7. reg [n:0] C;
  8. ingeter k;
  9. always@(X, Y, carryin) begin
  10. C[0] = carryin;
  11. // 此处相当于多次1-bit full-adder (continuous assignment)
  12. for (k=0; k<n; k=k+1) begin
  13. S[k]=X[k] ^ Y[k] ^ C[k];
  14. C[k+1] = (X[k] & Y[k]) | (X[k] & C[k]) | (Y[k] & C[k]);
  15. end
  16. carryout = C[n];
  17. end
  18. endmodule
  1. module addern(carryin, X, Y, S, carryout, overflow);
  2. parameter n = 32;
  3. input carryin;
  4. input [n-1:0] X, Y;
  5. output reg [n-1:0] S;
  6. output reg carryout, overflow;
  7. reg [n:0] C;
  8. ingeter k;
  9. always@(X, Y, carryin) begin
  10. {carryout, S} = X + Y + carryin;
  11. // 看不懂overflow是什么鬼
  12. overflow = carryout ^ X[n-1] ^ Y[n-1] ^ S[n-1];
  13. end
  14. endmodule

BCD就是写成二进制,然后每四位本应表示十六进制,但是在此表示十进制

  1. module bcdadd(Cin, X, Y, S, Cout);
  2. input Cin;
  3. input [3:0] X, Y;
  4. output reg [3:0] S;
  5. output reg Cout;
  6. reg [4:0] Z;
  7. always@(X, Y, Cin) begin
  8. Z = X + Y + Cin;
  9. if (Z < 10)
  10. {Cout, S} = Z;
  11. else
  12. {Cout, S} = Z + 6;
  13. end
  14. endmodule
7+5=12
7=0111
5=0101
1100>1010
1100+0110=10010
0001 0010 -> 12

Lecture 10

本节讲了:

感觉没啥好总结的,跳过之

Lecture 11

Sequential circuits are called finite state machines (FSM)(有限状态机)

Moore type: 输出只与state有关
Mealy type: 输出与state以及input有关

Moore State Model

input w, output z
z只有在上两个clock中w都是1的时候才为1,否则为0

Clockcycle 0 1 2 3 4 5 6 7 8 9 10
w 0 1 0 1 1 0 1 1 1 0 1
z 0 0 0 0 0 1 0 0 1 1 0

Mealy State Model

input w, output z
z只有在连续两次w都为1的时候才为1,否则为0

Clockcycle 0 1 2 3 4 5 6 7 8 9 10
w 0 1 0 1 1 0 1 1 1 0 1
z 0 0 0 0 1 0 0 1 1 0 0

感觉判断Moore和Mealy的方法,就是看input能否在当前clock直接对output造成影响。如果可以,是Mealy,否则为Moore
对于状态机的state table,以及借助那个什么表格来求Y1、Y2以及z的表达式,会在以后进行专题讲解

Lecture 12 & 13

完全不知所云……

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注