Loading

计算机组成原理

门电路实现

与非门

image-20241215140947686

image-20241215141004977

可以使用两个NMOS管串联跟两个PMOS管并联构成:

image-20241215141058910

NMOS管是当gate输入高电压导通,PMOS管是当gate输入低电压的时候导通。

对于其他门电路:
image-20241215141519980

等价电路:交换律、结合律、分配律、德摩根律、幂等律、双重否定律

与非门Verilog HDL表示

module Nand(input a, b, output out);
  nmos n1(o1, 0, b);
  nmos n2(out, o1, a);

  pmos p1(out, 1, b);
  pmos p2(out, 1, a);
endmodule

与门实现(用两个与非门连接)

image-20241215142551445

module And(input a, b, output out);
  Nand g1(a, b, AnandB);
  Nand g2(AnandB, AnandB, out);
endmodule

非门实现(两个输入一样的与非门)

image-20241215142944758


module Not(input in, output out);
  // your code here
  Nand  g1(in,in,out);
endmodule

或门实现(三个与非门)

image-20241215143059883

module Or(input a, b, output out);
  // your code here
  wire nand_a, nand_b;

    // 第一个NAND门,模拟 NAND(A, A)
    Nand nand1(a, a, nand_a);

    // 第二个NAND门,模拟 NAND(B, B)
    Nand nand2(b, b, nand_b);

    // 最后一个NAND门,模拟 NAND(nand_a, nand_b),得到 OR 结果
    Nand nand3(nand_a, nand_b, out);
endmodule

或非门(一个或门和一个非门)

image-20241215143505238

module Nor(input a, b, output out);
  // your code here
       wire out1;
	Or g1(a,b,out1);
	Nand g2(out1,out1,out);
endmodule

异或门(一个或门和一个与非门并联,再接一个与门)

image-20241215143626378

module Xor(input a, b, output out);
  // your code here
wire out1,out2;
  Or g1(a,b,out1);
  Nand g2(a,b,out2);
  And g3(out1,out2,out);
endmodule

加法器实现

先看半加器

通过一位的加法的真值表:

image-20241215144219054

sum符合异或门特性,carry符合与门特性,得到:

image-20241215144445213

module HalfAdder(input a,b, output sum, carry);
  // your code here
  Xor g1(a,b,sum);
  And g2(a,b,carry);
endmodule

全加器(考虑进位)

真值表:image-20241215144741492

image-20241215145208548

module FullAdder(input a,b,c, output sum, carry);
  // your code here
 wire AB,carry1,carry2;
  HalfAdder g1(a,b,AB,carry1);
  HalfAdder g2(AB,c,sum,carry2);
  Or g3(carry1,carry2,carry);
endmodule

16位加法器

module Add16(input[15:0] a,b, output[15:0] out);
  // your code here
 wire [15:0] c;
  FullAdder g01(a[0],b[0],1'b0,out[0],c[0]);
  FullAdder g02(a[1],b[1],c[0],out[1],c[1]);
  FullAdder g03(a[2],b[2],c[1],out[2],c[2]);
  FullAdder g04(a[3],b[3],c[2],out[3],c[3]);
  FullAdder g05(a[4],b[4],c[3],out[4],c[4]);
  FullAdder g06(a[5],b[5],c[4],out[5],c[5]);
  FullAdder g07(a[6],b[6],c[5],out[6],c[6]);
  FullAdder g08(a[7],b[7],c[6],out[7],c[7]);
  FullAdder g09(a[8],b[8],c[7],out[8],c[8]);
  FullAdder g10(a[9],b[9],c[8],out[9],c[9]);
  FullAdder g11(a[10],b[10],c[9],out[10],c[10]);
  FullAdder g12(a[11],b[11],c[10],out[11],c[11]);
  FullAdder g13(a[12],b[12],c[11],out[12],c[12]);
  FullAdder g14(a[13],b[13],c[12],out[13],c[13]);
  FullAdder g15(a[14],b[14],c[13],out[14],c[14]);
  FullAdder g16(a[15],b[15],c[14],out[15],c[15]);
endmodule

减法

负数的补码由他的正数按位取反再加1

image-20241215150011955

带溢出判断的加法器

两正数相加结果为负数=正溢

两负数相加结果为正=负溢

image-20241215150618951

image-20241215151250994

寄存器存储器的实现

时钟

image-20241215152432176

image-20241215152502643

多路选择器(multiplexor)

image-20241215152651951

sel = 0,选择a作为输出

sel =1,选择b作为输出

/** 
 * Multiplexor:
 * if (sel == 0) out = a 
 *   else out = b
 */

module Mux(input a, b, sel, output out);
  Not g1(sel, nsel);
  And g2(a, nsel, o1);
  And g3(b, sel, o2);
  Or  g4(o1, o2, out);
endmodule

16位的多路选择器

/**
 * 16-bit multiplexor: 
 * for i = 0..15 out[i] = a[i] if sel == 0 
 *                        b[i] if sel == 1
 */

module Mux16(input[15:0] a, b, input sel, output[15:0] out);
  Mux g15(a[15], b[15], sel, out[15]);
  Mux g14(a[14], b[14], sel, out[14]);
  Mux g13(a[13], b[13], sel, out[13]);
  Mux g12(a[12], b[12], sel, out[12]);
  Mux g11(a[11], b[11], sel, out[11]);
  Mux g10(a[10], b[10], sel, out[10]);
  Mux g09(a[9],  b[9],  sel, out[9]);
  Mux g08(a[8],  b[8],  sel, out[8]);
  Mux g07(a[7],  b[7],  sel, out[7]);
  Mux g06(a[6],  b[6],  sel, out[6]);
  Mux g05(a[5],  b[5],  sel, out[5]);
  Mux g04(a[4],  b[4],  sel, out[4]);
  Mux g03(a[3],  b[3],  sel, out[3]);
  Mux g02(a[2],  b[2],  sel, out[2]);
  Mux g01(a[1],  b[1],  sel, out[1]);
  Mux g00(a[0],  b[0],  sel, out[0]);
endmodule

4way/8way 多路选择器

即输入4个情况/输入8个情况

image-20241215153244300

多路复用器(Demultiplexor)

image-20241215153356775

/**
 * Demultiplexor:
 * if sel == 0, a= in, b = 0;
 * if sel == 1, a= 0, b = in;
 */

module DMux(input in, sel, output a, b);
  Not g1(sel, nsel);
  And g2(nsel, in, a);
  And g3(sel,  in, b);
endmodule

4way/8way 多路复用器

即输出4个情况/输出8个情况

image-20241215153625136

SR锁存器

image-20241215153930117

时钟SR锁存器(当时钟=1时候,输出才受r 和s 影响,当时钟=0,输出保持之前的值)

image-20241215173719075

module SRFF (input R, clock, S, output Q, Q_dot);
  // your code here
  wire Rout,Sout;
   And g1(R,clock,Rout);
  And g2(S,clock,Sout);
  Nor g3(Rout,Q_dot,Q);
  Nor g4(Sout,Q,Q_dot);
endmodule

D锁存器(就是把SR锁存器两个输入变成一个输入)也叫电平触发

image-20241215174841523

image-20241215175213710

D触发器(两个时钟SR锁存器构成),属于边沿触发,只有当时钟从0->1时才是输出等于输入,其他情况保持之前的值。

image-20241215175327690

image-20241215175633373

D触发器的实现

image-20241215180155754

module DFF(input in, clock, load, output out);
  // your code here
  wire in1,inNot,clockNot,Q,Q_,Q_dot;
  Mux g1(out,in,load,in1);
  Not g3(in1,inNot);
  Not g4(clock,clockNot);
  SRFF g2(in1,clockNot,inNot,Q, Q_);
  SRFF g5(Q,clock,Q_,out, Q_dot);

endmodule

16位的寄存器(16个D触发器),当load=1,时钟从0->1的时候,输出等于输入。当load=0,就保持之前的值。

/**
 * 16-bit register:
 * If clk[t] == 1 then out[t+1] = in[t]
 * else out does not change
 */

module Register(input[15:0] in, input clock, load, output[15:0] out);
  DFF g01(in[15], clock, load, out[15]);
  DFF g02(in[14], clock, load, out[14]);
  DFF g03(in[13], clock, load, out[13]);
  DFF g04(in[12], clock, load, out[12]);
  DFF g05(in[11], clock, load, out[11]);
  DFF g06(in[10], clock, load, out[10]);
  DFF g07(in[9],  clock, load, out[9]);
  DFF g08(in[8],  clock, load, out[8]);
  DFF g09(in[7],  clock, load, out[7]);
  DFF g10(in[6],  clock, load, out[6]);
  DFF g11(in[5],  clock, load, out[5]);
  DFF g12(in[4],  clock, load, out[4]);
  DFF g13(in[3],  clock, load, out[3]);
  DFF g14(in[2],  clock, load, out[2]);
  DFF g15(in[1],  clock, load, out[1]);
  DFF g16(in[0],  clock, load, out[0]);
endmodule

8个寄存器组合成一个RAM8的存储器,input[2:0] address有3位也就是八个地址,分别对应八个寄存器

通过多路复用器,当load=1时,选择把输入存储到哪个寄存器里,比如load=1,address=1,就把loadB设为1,当时钟0->1时候,o1=in(输出等于输入)

然后再使用多路选择器,通过地址选择哪个寄存器作为输出。

module RAM8(input[15:0] in, input clk, load, input[2:0] address, output[15:0] out);
  wire[15:0] o0,o1,o2,o3,o4,o5,o6,o7;
	
  DMux8Way g0(load, address, loadA, loadB, loadC, loadD, loadE, loadF, loadG, loadH);
  
  Register r0(in, clk, loadA, o0);
  Register r1(in, clk, loadB, o1);
  Register r2(in, clk, loadC, o2);
  Register r3(in, clk, loadD, o3);
  Register r4(in, clk, loadE, o4);
  Register r5(in, clk, loadF, o5);
  Register r6(in, clk, loadG, o6);
  Register r7(in, clk, loadH, o7);
  
  Mux8Way16 g1(o0, o1, o2, o3, o4, o5, o6, o7, address, out);
endmodule

8个RAM8存储器组合成RAM64,地址范围0-5,即2的6次方64个地址

address[5:3] 前三位八个地址,作为8个RAM8的选择

address[2:0] 后三位8个地址,作为8个寄存器的选择

module RAM64(input [15:0] in, input clk,load, input [5:0] address, output [15:0] out);
    wire[15:0] o1, o2, o3, o4, o5, o6, o7, o8;
    DMux8Way d1(load, address[5:3], loadA, loadB, loadC, loadD, loadE, loadF, loadG, loadH);

    RAM8 r1(in, clk, loadA, address[2:0], o1);
    RAM8 r2(in, clk, loadB, address[2:0], o2);
    RAM8 r3(in, clk, loadC, address[2:0], o3);
    RAM8 r4(in, clk, loadD, address[2:0], o4);
    RAM8 r5(in, clk, loadE, address[2:0], o5);
    RAM8 r6(in, clk, loadF, address[2:0], o6);
    RAM8 r7(in, clk, loadG, address[2:0], o7);
    RAM8 r8(in, clk, loadH, address[2:0], o8);

    Mux8Way16 m1(o1, o2, o3, o4, o5, o6, o7, o8, address[5:3], out);
endmodule

8个RAM64存储器组合成RAM512,地址范围0-8,即2的9次方512个地址

module RAM512(input [15:0] in, input clk,load, input [8:0] address, output [15:0] out);
    // your code here
    wire[15:0] o1, o2, o3, o4, o5, o6, o7, o8;
    DMux8Way d1(load, address[8:6], loadA, loadB, loadC, loadD, loadE, loadF, loadG, loadH);
    
    RAM64 r1(in, clk, loadA, address[5:0], o1);
    RAM64 r2(in, clk, loadB, address[5:0], o2);
    RAM64 r3(in, clk, loadC, address[5:0], o3);
    RAM64 r4(in, clk, loadD, address[5:0], o4);
    RAM64 r5(in, clk, loadE, address[5:0], o5);
    RAM64 r6(in, clk, loadF, address[5:0], o6);
    RAM64 r7(in, clk, loadG, address[5:0], o7);
    RAM64 r8(in, clk, loadH, address[5:0], o8);
    Mux8Way16 m1(o1, o2, o3, o4, o5, o6, o7, o8, address[8:6], out);

endmodule

执行会很慢。需要verilog高级语法。

16位CPU指令设计

指令设计

D寄存器:仅用来存储数据值

A寄存器:存储地址或数据

A指令:用来为A寄存器设置15位的值

image-20241215195758828

C指令:完成算术逻辑操作,存储器读写操作,控制流跳转操作

image-20241215195809369

介绍C指令的comp域,a=0,按照左边计算。a=1,按照右边计算。

image-20241215200009357

介绍C指令的dest域,他是用来指定comp计算出来的值存储的地方。

d1对应A寄存器,1,0,0表示把结果存储在A寄存器

d2对应D寄存器,0,1,0表示把结果存储在D寄存器

d3对应Memory[A],0,0,1表示把结果存住在Memory[A]

三个都为0表示不存储值。三个都为1表示这三个地方都存储。

image-20241215200409771

介绍C指令的jump域

0 0 0 不跳转

1 1 1无条件跳转

其他情况,根据comp计算出来的结果判断,如:0 1 0,out=0,跳转

image-20241215201008640###

ALU实现

ALU主要实现C指令comp域描述的计算,他有两个16位的输入系x,y,一个16位的输出 out,6个控制输入zx,nx,zy,ny,f,no,2个控制输出zr,ng

image-20241215202822495

ALU在六个控制输入不同的组合下可以实现不同的个功能:comp域六位对应zx,nx,zy,ny,f,no

image-20241215203135556

if可以使用多路选择器来进行判断,ALU数据通路图:

image-20241215204430448

Or16way

/**
 * 16-way Or: 
 * out = (in[0] or in[1] or ... or in[15])
 */

module Or16Way(input[15:0] in,output out);
    // your code here
wire out1,out2,out3,out4,out5,out6,out7,out8,out9,out10,out11,out12,out13,out14;
     Or g1(in[0],in[1],out1);
    Or g2(out1,in[2],out2);
    Or g3(out2,in[3],out3);
    Or g4(out3,in[4],out4);
    Or g5(out4,in[5],out5);
    Or g6(out5,in[6],out6);
    Or g7(out6,in[7],out7);
    Or g8(out7,in[8],out8);
    Or g9(out8,in[9],out9);
    Or g10(out9,in[10],out10);
    Or g11(out10,in[11],out11);
    Or g12(out11,in[12],out12);
    Or g13(out12,in[13],out13);
    Or g14(out13,in[14],out14);
    Or g15(out14,in[15],out);

endmodule

IsNeg

module IsNeg(input[15:0] in, output out);
  // your code here
 Or g1(in[15],1'b0,out);

endmodule

ALU

/**
 * The ALU (Arithmetic Logic Unit).
 * Computes one of the following functions:
 * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y,
 * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, 
 * according to 6 input bits denoted zx,nx,zy,ny,f,no.
 * In addition, the ALU computes two 1-bit outputs:
 * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0;
 * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0.
 */

// Implementation: the ALU logic manipulates the x and y inputs
// and operates on the resulting values, as follows:
// if (zx == 1) set x = 0        // 16-bit constant
// if (nx == 1) set x = !x       // bitwise not
// if (zy == 1) set y = 0        // 16-bit constant
// if (ny == 1) set y = !y       // bitwise not
// if (f == 1)  set out = x + y  // integer 2's complement addition
// if (f == 0)  set out = x & y  // bitwise and
// if (no == 1) set out = !out   // bitwise not
// if (out == 0) set zr = 1
// if (out < 0) set ng = 1


module ALU(input[15:0] x, y, input zx,nx,zy,ny,f,no, output[15:0] out, output zr, ng);
  wire[15:0] x1, notx1, x2, y1, noty1, y2, andxy, addxy, o1, noto1, o2;
  wire notzr;
  // your code here, use Mux16,Not16,Add16,And16,Or16Way,IsNeg to implement
  // if (zx == 1) set x = 0  
	Mux16	g1(x,16'h0,zx,x1);
	
	
	
  // if (nx == 1) set x = !x
	Not16   g2(x1,notx1);
	Mux16   g3(x1,notx1,nx,x2);

  // if (zy == 1) set y = 0
  	Mux16	g4(y,16'h0,zy,y1);

  // if (ny == 1) set y = !y
	Not16   g5(y1,noty1);
	Mux16   g6(y1,noty1,ny,y2);	

  // addxy = x + y
  	Add16   g7(x2,y2,addxy);

  // andxy = x & y
  	And16   g8(x2,y2,andxy);

  // if (f == 1)  set out = x + y else set out = x & y
  	Mux16   g9(andxy,addxy,f,o1);

  // if (no == 1) set out = !out
  	Not16   g10(o1,noto1);
	Mux16   g11(o1,noto1,no,out);


  // zr
  	
	Or16Way g12(out,notzr);	
	Not g13(notzr,zr);
  // ng
	IsNeg g14(out,ng);
  
endmodule
posted @ 2024-12-15 20:49  suehoo  阅读(9)  评论(0编辑  收藏  举报