1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Homework 4 Update “Multiplication” function for CPU

9 269 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 544,44 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

VLSI DESIGN AUTOMATIONHomework 4Update “Multiplication” functionfor CPU and writing test benchVLSI DESIGN AUTOMATIONVLSI DESIGN AUTOMATIONHomework 4Update “Multiplication” functionfor CPU and writing test benchVLSI DESIGN AUTOMATIONHomework 4Update “Multiplication” functionfor CPU and writing test benchHomework 4Update “Multiplication” functionfor CPU and writing test bench

Trang 1

VLSI DESIGN AUTOMATION

Homework #4

Update “Multiplication” function for CPU and writing test bench

Student: Bui Huu Nguyen

Student ID: 2016310539 Submit date: 2016/11/03

Trang 2

A Update CPU code that has “Multiplication” function

// Project: Simple CPU

// File : CPU_Defs.sv

package cpu_defs;

parameter WORD_W = 8;

parameter OP_W = 3;

enum logic[2:0]

{

LOAD=3'b000,

STORE=3'b001,

ADD=3'b010,

SUB=3'b011,

BNE=3'b100,

MUL = 3'b101 // add multiply function

} opcodes;

endpackage

// Project: Simple CPU

// File : CPU.sv

//

import cpu_defs::*;

module CPU (input logic clock, n_reset, inout wire [WORD_W-1:0] sysbus);

CPU_bus bus (.*);

sequencer s1 (.*);

IR i1 (.*);

PC p1 (.*);

ALU a1 (.*);

RAM r1 (.*);

endmodule

// Project: Simple CPU

// File : PC.sv

//

import cpu_defs::*;

module PC (CPU_bus.PC_port bus);

logic [WORD_W-OP_W-1:0] count;

assign bus.sysbus = bus.PC_bus ?

{{OP_W{1'b0}},count} : 'z;

always_ff @(posedge bus.clock, negedge

bus.n_reset)

begin

if (!bus.n_reset)

count <= 0;

else

if (bus.load_PC)

if (bus.INC_PC)

count <= count + 1;

else

count <= bus.sysbus;

end

endmodule

// Project: Simple CPU

// File : IR.sv

//

import cpu_defs::*;

module IR (CPU_bus.IR_port bus);

logic [WORD_W-1:0] instr_reg;

assign bus.sysbus = bus.Addr_bus ? {{OP_W{1'b0}},instr_reg[WORD_W-OP_W-1:0]} : 'z;

always_comb bus.op = instr_reg[WORD_W-1:WORD_W-OP_W];

always_ff @(posedge bus.clock, negedge bus.n_reset)

begin

if (!bus.n_reset) instr_reg <= 0;

else

if (bus.load_IR) instr_reg <= bus.sysbus;

end endmodule

Trang 3

// Project: Simple CPU

// File : CPU_Bus_IF.sv

//

import cpu_defs::*;

interface CPU_bus (input logic clock, n_reset,

inout wire [WORD_W-1:0] sysbus);

logic ACC_bus, load_ACC, PC_bus, load_PC,

load_IR,

load_MAR, MDR_bus, load_MDR, ALU_ACC,

ALU_add,

ALU_sub,ALU_mul,INC_PC, Addr_bus, CS, R_NW,

z_flag, ov_add_flag, ov_mul_flag;

logic [OP_W-1:0] op;

modport IR_port(

input clock, n_reset, Addr_bus, load_IR,

inout sysbus,

output op);

modport RAM_port (

input clock, n_reset, MDR_bus,

load_MDR, load_MAR, CS, R_NW,

inout sysbus);

modport ALU_port (

input clock, n_reset, ACC_bus,

load_ACC, ALU_ACC, ALU_add, ALU_sub,

ALU_mul,

inout sysbus,

output z_flag, ov_add_flag, ov_mul_flag);

modport PC_port (

input clock, n_reset, PC_bus, load_PC, INC_PC,

inout sysbus);

modport seq_port (input clock, n_reset, z_flag,

ov_add_flag, ov_mul_flag,

input op,

output ACC_bus, load_ACC, PC_bus,

load_PC, load_IR, load_MAR,

MDR_bus, load_MDR, ALU_ACC,

ALU_add, ALU_sub, ALU_mul, INC_PC,

Addr_bus, CS, R_NW);

endinterface

// Project: Simple CPU

// File : ALU.sv

//

import cpu_defs::*;

module ALU (CPU_bus.ALU_port bus);

logic [WORD_W-1:0] acc;

logic [WORD_W-1:0] overflow_add;

logic [WORD_W-1:0] overflow_mul;

assign bus.sysbus = bus.ACC_bus ? acc : 'z; assign bus.z_flag = acc == 0 ? '1 : '0;

assign bus.ov_add_flag = overflow_add != 0 ? '1 : '0;

assign bus.ov_mul_flag = overflow_mul != 0 ? '1 : '0;

always_ff @(posedge bus.clock, negedge bus.n_reset)

begin

if (!bus.n_reset) begin

acc <= 0;

overflow_mul<=0;

overflow_add <=0;

end else

if (bus.load_ACC)

if (bus.ALU_ACC) begin

if (bus.ALU_add)

{overflow_add,acc} <= acc + bus.sysbus;

else if (bus.ALU_sub) acc <= acc - bus.sysbus;

else if (bus.ALU_mul) // multi function

{overflow_mul,acc} <= acc * bus.sysbus; // multiplication function

end else acc <= bus.sysbus;

end // always_ff endmodule

Trang 4

// Project: Simple CPU

// File : RAM.sv

//

import cpu_defs::*;

module RAM (CPU_bus.RAM_port bus);

logic [WORD_W-1:0] mdr;

logic [WORD_W-OP_W-1:0] mar;

logic [WORD_W-1:0] mem

[0:(1<<(WORD_W-OP_W))-1];

int i;

assign bus.sysbus = bus.MDR_bus ? mdr : 'z;

always_ff @(posedge bus.clock, negedge

bus.n_reset)

begin

if (!bus.n_reset)

begin

mdr <= 0;

mar <= 0;

mem[0] <= {LOAD, 5'd16};// check add function

mem[1] <= {ADD, 5'd17};

mem[2] <= {STORE, 5'd18};

mem[3] <= {LOAD, 5'd19};// check sub function

mem[4] <= {SUB, 5'd20};

mem[5] <= {STORE, 5'd21};

mem[6] <= {LOAD, 5'd22}; // check mul function

mem[7] <= {MUL, 5'd23};

mem[8] <= {STORE, 5'd24};

mem[9] <= {LOAD, 5'd25}; // check overflow add

mem[10] <= {ADD, 5'd26};

mem[11] <= {STORE, 5'd27};

mem[12] <= {LOAD, 5'd28}; //check overflow mul

mem[13] <= {MUL, 5'd29};

mem[14] <= {STORE,5'd30};

mem[15] <= 0;

mem[16] <= 3;

mem[17] <= 10;

mem[18] <= 0;

mem[19] <= 120;

mem[20] <= 20;

mem[21] <= 0;

mem[22] <= 8;

mem[23] <= 10;

mem[24] <= 0;

mem[25] <= 140;

mem[26] <= 150;

mem[27] <= 0;

mem[28] <= 100;

mem[29] <= 10;

mem[30] <= 0;

mem[31] <= 0;

end // if (!bus.n_reset) else

if (bus.load_MAR) mar <= bus.sysbus[WORD_W-OP_W-1:0]; else if (bus.load_MDR)

mdr <= bus.sysbus;

else if (bus.CS)

if (bus.R_NW) mdr <= mem[mar];

else mem[mar] <= mdr;

end // always_ff endmodule

Trang 5

// Project: Simple CPU

// File : Sequencer.sv

//

import cpu_defs::*;

module sequencer (CPU_bus.seq_port bus);

enum {

s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10

} state;

always_ff @(posedge bus.clock, negedge

bus.n_reset)

begin: seq

if (!bus.n_reset)

state <= s0;

else

case (state)

s0: state <= s1;

s1: state <= s2;

s2: state <= s3;

s3: if (bus.op == STORE)

state <= s4;

else

state <= s6;

s4: state <= s5;

s5: state <= s0;

s6: if (bus.op == LOAD)

state <= s7;

else if (bus.op == BNE)

if (bus.z_flag)

state <= s9;

else

state <= s10;

else

state <= s8;

s7: state <= s0;

s8: state <= s0;

s9: state <= s0;

s10: state <= s0;

endcase // state

end // always_ff

always_comb

begin: com

// reset all the control signals to default

bus.ACC_bus = '0;

bus.load_ACC = '0;

bus.PC_bus = '0;

bus.load_PC = '0;

bus.load_IR = '0;

bus.load_MAR = '0;

bus.MDR_bus = '0;

bus.load_MDR = '0;

bus.ALU_ACC = '0;

bus.ALU_add = '0;

bus.ALU_sub = '0;

bus.ALU_mul = '0; // bus of multiply bus.INC_PC = '0;

bus.Addr_bus = '0;

bus.CS = '0;

bus.R_NW = '0;

case (state) s0: begin bus.PC_bus = '1;

bus.load_MAR = '1;

bus.INC_PC = '1;

bus.load_PC = '1;

end s1: begin bus.CS = '1;

bus.R_NW = '1;

end s2: begin bus.MDR_bus = '1;

bus.load_IR = '1;

end s3: begin bus.Addr_bus = '1;

bus.load_MAR = '1;

end s4: begin bus.ACC_bus = '1;

bus.load_MDR = '1;

end s5: begin bus.CS = '1;

end s6: begin bus.CS = '1;

bus.R_NW = '1;

end s7: begin bus.load_ACC = '1;

Trang 6

s8: begin

bus.MDR_bus = '1;

bus.ALU_ACC = '1;

bus.load_ACC = '1;

if (bus.op == ADD)

bus.ALU_add = '1;

else if (bus.op == SUB)

bus.ALU_sub = '1;

else if (bus.op == MUL) //

bus.ALU_mul = '1; // add multiply

end

s9: begin bus.MDR_bus = '1;

bus.load_PC = '1;

end s10: begin

bus.load_PC = '1; //

bus.INC_PC = '0; //

bus.MDR_bus = '1; // add multiply MUL = 3'b101

end endcase // state end // always_comb endmodule

// Project: Simple CPU

// CPU_test bench.sv

`timescale 1 ns / 100 ps

import cpu_defs::*;

module CPU_tb();

reg clock, n_reset;

wire [WORD_W-1:0] sysbus;

// Clock generator

initial begin

clock=0;

forever #10 clock=~clock;

end

initial begin

n_reset=0;

@(posedge clock)

n_reset=1;

end

CPU CPU_u1(clock, n_reset, sysbus);

endmodule

B Results simulation

1 mem[0] <= {LOAD, 5'd16};// check add

function

mem[1] <= {ADD, 5'd17};

mem[2] <= {STORE, 5'd18};…………

……

mem[16] <= 3;

mem[17] <= 10;

Discussion: Step1, at mem[1] region, CPU load data

from “mem[16]“ region to “acc” register in ALU block Step2, at mem[1], CPU load data from “mem[17]” to

“sysbus” then operate summation between “acc” with

“sysbus” and store in “acc” register Step3, at mem[2], store data in “acc” register into “mem[18]” region

Result: 3+10 = 13  in acc and mem[18]

Trang 7

2 mem[3] <= {LOAD, 5'd19};// check sub

function

mem[4] <= {SUB, 5'd20};

mem[5] <= {STORE, 5'd21}; ………

……

mem[19] <= 120;

mem[20] <= 20;

Discussion: Step4, at mem[3] region, CPU load data

from “mem[19]“ region to “acc” register in ALU block Step5, at mem[4], CPU load data from “mem[20]” to

“sysbus” then operate subtraction between “acc” with “sysbus” and store in “acc” register Step6, at

mem[5], store data in “acc” register into “mem[21]”

region

Result: 120-20 = 100  in acc and mem[21]

3 mem[6] <= {LOAD, 5'd22}; // check mul

function

mem[7] <= {MUL, 5'd23};

mem[8] <= {STORE, 5'd24};………

……

mem[22] <= 8;

mem[23] <= 10;

Discussion: Step7, at mem[6] region, CPU load data

from “mem[22]“ region to “acc” register in ALU block Step8, at mem[7], CPU load data from “mem[23]” to

“sysbus” then operate multiplication between “acc” with “sysbus” and store in “acc” register Step9, at

mem[8], store data in “acc” register into “mem[24]”

region

Result: 8*10 = 80  in acc and mem[21]

Load data (3) from mem[16] to acc Add

Load data (10) from mem[17] to sysbus Store result in acc

Load data (120) from mem[19] to acc Sub

Load data (20) from mem[20] to sysbus Store result in acc

Trang 8

4 mem[9] <= {LOAD, 5'd25}; // check

overflow add

mem[10] <= {ADD, 5'd26};

mem[11] <= {STORE, 5'd27};………

……

mem[25] <= 140;

mem[26] <= 150;

Discussion: Step10, at mem[9] region, CPU load data

from “mem[25]“ region to “acc” register in ALU block Step11, at mem[10], CPU load data from “mem[26]”

to “sysbus” then operate summation between “acc” with “sysbus” and store in “acc” register Step12, at

mem[11], store data in “acc” register into “mem[27]”

region

Result: 140*150 = 290 or 8d(290-256) = 8d34  in acc

and mem[21] Due value 290 lager than 256 so ov_add_flag == 1.

5 mem[12] <= {LOAD, 5'd28}; //check

overflow mul

mem[13] <= {MUL, 5'd29};

mem[14] <= {STORE,5'd30};……

……

mem[28] <= 100;

mem[29] <= 10;

Discussion: Step13, at mem[12] region, CPU load data

from “mem[28]“ region to “acc” register in ALU block Step14, at mem[13], CPU load data from “mem[29]”

to “sysbus” then operate multiplication between

“acc” with “sysbus” and store in “acc” register Step15,

at mem[14], store data in “acc” register into

“mem[30]” region

Load data (8) from mem[22] to acc Mul

Load data (10) from mem[23] to sysbus Store result in acc

Load data (140 or -8d116) from mem[25]

to acc

Add

Load data (150 or -8d106 ) from mem[26] to sysbus

Store result in acc

ov_add_flag

Trang 9

Result: 100*10 = 1000 or 8d(1000-4*256) = -8d24 

in acc and mem[30] Due value 1000 lager than 256 so ov_mul_flag == 1.

Load data (100) from mem[25] to acc Mul

Load data (10) from mem[29] to sysbus Store result in acc

ov_mul_flag

Ngày đăng: 15/11/2016, 04:05

TỪ KHÓA LIÊN QUAN