0% found this document useful (0 votes)
10 views18 pages

Simple Processor Design in Verilog

The document describes a simple processor design capable of executing four instructions: mv, mvi, add, and sub. It includes the Verilog code for the processor, its testbench, and an extended version with external memory handling. Additionally, it features debounce logic for clock signals and a program counter for instruction fetching.

Uploaded by

dtdatna
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views18 pages

Simple Processor Design in Verilog

The document describes a simple processor design capable of executing four instructions: mv, mvi, add, and sub. It includes the Verilog code for the processor, its testbench, and an extended version with external memory handling. Additionally, it features debounce logic for clock signals and a program counter for instruction fetching.

Uploaded by

dtdatna
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

P1

// a simple processor
//可以实现 4 种指令。

module Part1_processor(DIN,Resetn,Clock,Run,Done,BusWires);
input [15:0] DIN; //16-bit 数据输入
input Resetn,Clock,Run;
output Done;
output [15:0] BusWires;

//declare variables

reg [15:0] BusWires;


reg [0:7] Rin,Rout; //8 个 16-bit 寄存器的输入/出控制
reg [15:0] Sum;
reg IRin,Done,DINout,Ain,Gin,Gout,AddSub;
wire [1:0] Tstep_Q; //4 个阶段计数输出
wire [2:0] I; //3-bit 指令码
wire [0:7] Xreg,Yreg; //2 个 8-bit 寄存器
wire [15:0] R0,R1,R2,R3,R4,R5,R6,R7,A,G; //9 个 16-bit 寄存器
wire [1:9] IR; //IIIXXXYYY
wire [1:10] Sel; //多路器的选择位
wire Clear=~Resetn | Done | (~Run & ~Tstep_Q[1] & ~Tstep_Q[0]);
//clear
upcount Tstep(Clear,Clock,Tstep_Q); //T0-T3 4 个阶段
assign I=IR[1:3]; //指令位
dec3to8 decX(IR[4:6],1'b1,Xreg); //译码,用于选择 R0-R7
dec3to8 decY(IR[7:9],1'b1,Yreg);

//指令列表:
//000: mv
//001: mvi
//010: add
//011: sub

always @(Tstep_Q or I or Xreg or Yreg)


begin
//specify initial values
Done=1'b0;
Ain=1'b0;
Gin=1'b0;
Gout=1'b0;
AddSub=1'b0;
IRin=1'b0;
DINout=1'b0;
Rin=8'b0;
Rout=8'b0;

case(Tstep_Q)
2'b00: //store DIN in IR in time step 0
begin
IRin=1'b1;
end
2'b01: //define signals in time step 1
case(I)
3'b000: //mv Rx,Ry
begin
Rout=Yreg;
Rin=Xreg;
Done=1'b1;
end
3'b001: //mvi Rx,#D
begin
DINout=1'b1;
Rin=Xreg;
Done=1'b1;
end
3'b010,2'b011: //add,sub
begin
Rout=Xreg;
Ain=1'b1;
end
default: ;
endcase
2'b10: //define signals in time step 2
case(I)
3'b010: //add
begin
Rout=Yreg;
Gin=1'b1;
end
3'b011: //sub
begin
Rout=Yreg;
AddSub=1'b1;
Gin=1'b1;
end
default: ;
endcase
2'b11: //define signals in time step 3
case(I)
3'b010,3'b011: //add,sub
begin
Gout=1'b1;
Rin=Xreg;
Done=1'b1;
end
default: ;
endcase
endcase
end

regn reg_0(BusWires,Rin[0],Clock,R0);
//instantiate other registers and the adder/subtracter unit
regn reg_1(BusWires,Rin[1],Clock,R1);
regn reg_2(BusWires,Rin[2],Clock,R2);
regn reg_3(BusWires,Rin[3],Clock,R3);
regn reg_4(BusWires,Rin[4],Clock,R4);
regn reg_5(BusWires,Rin[5],Clock,R5);
regn reg_6(BusWires,Rin[6],Clock,R6);
regn reg_7(BusWires,Rin[7],Clock,R7);
regn reg_A(BusWires,Ain,Clock,A);
regn #(.n(9)) reg_IR(DIN[15:7],IRin,Clock,IR);

//alu
always @(AddSub or A or BusWires)
begin
if(!AddSub)
Sum=A+BusWires;
else
Sum=A-BusWires;
end

regn reg_G(Sum,Gin,Clock,G);

//define the bus


assign Sel={Rout,Gout,DINout};

always @(*)
begin
if(Sel==10'b10_0000_0000)
BusWires=R0;
else if(Sel==10'b01_0000_0000)
BusWires=R1;
else if(Sel==10'b00_1000_0000)
BusWires=R2;
else if(Sel==10'b00_0100_0000)
BusWires=R3;
else if(Sel==10'b00_0010_0000)
BusWires=R4;
else if(Sel==10'b00_0001_0000)
BusWires=R5;
else if(Sel==10'b00_0000_1000)
BusWires=R6;
else if(Sel==10'b00_0000_0100)
BusWires=R7;
else if(Sel==10'b00_0000_0010)
BusWires=G;
else
BusWires=DIN;
end
endmodule

module upcount(Clear,Clock,Q);
input Clear,Clock;
output [1:0] Q;
reg [1:0] Q;

always @(posedge Clock)


if(Clear)
Q<=2'b0;
else
Q<=Q+1'b1;
endmodule

module dec3to8(W,En,Y);
input [2:0] W;
input En;
output [0:7] Y;
reg [0:7] Y;

always @(W or En)


begin
if(En==1)
case(W)
3'b000: Y=8'b1000_0000;
3'b001: Y=8'b0100_0000;
3'b010: Y=8'b0010_0000;
3'b011: Y=8'b0001_0000;
3'b100: Y=8'b0000_1000;
3'b101: Y=8'b0000_0100;
3'b110: Y=8'b0000_0010;
3'b111: Y=8'b0000_0001;
endcase
else
Y=8'b0000_0000;
end
endmodule

module regn(R,Rin,Clock,Q);
parameter n=16;
input [n-1:0] R;
input Rin,Clock;
output [n-1:0] Q;
reg [n-1:0] Q;

always @(posedge Clock)


if(Rin)
Q<=R;
endmodule

P1_tb
`timescale 1ns/1ps
module tb_proc;
reg [15:0] DIN;
reg Resetn, Clock, Run;
wire Done;
wire [15:0] BusWires;

// Instantiate the processor


Part1_processor uut (
.DIN(DIN),
.Resetn(Resetn),
.Clock(Clock),
.Run(Run),
.Done(Done),
.BusWires(BusWires)
);

// Internal signal access


wire [8:0] IR = [Link];
wire [1:0] Tstep_Q = uut.Tstep_Q;
wire [15:0] Sum = [Link];
wire [15:0] A = uut.A;
wire [15:0] G = uut.G;
wire [0:7] Rin = [Link];
wire [0:7] Rout = [Link];
wire IRin = [Link];
wire DINout = [Link];
wire Ain = [Link];
wire Gin = [Link];
wire Gout = [Link];
wire AddSub = [Link];
wire [15:0] R0 = uut.R0;
wire [15:0] R1 = uut.R1;
wire [15:0] R2 = uut.R2;
wire [15:0] R3 = uut.R3;
wire [15:0] R4 = uut.R4;
wire [15:0] R5 = uut.R5;
wire [15:0] R6 = uut.R6;
wire [15:0] R7 = uut.R7;
wire [0:7] Xreg = [Link];
wire [0:7] Yreg = [Link];
wire [1:10] Sel = [Link];

// Clock generation
initial begin
Clock = 0;
forever #5 Clock = ~Clock;
end
// Dump waveform
initial begin
$dumpfile("[Link]");
$dumpvars(0, tb_proc);
end

// Monitor internal signals


initial begin
$monitor("Time=%0t | Clock=%b | Resetn=%b | Run=%b | Done=%b |
Tstep_Q=%b | IR=%b | BusWires=%h | Sum=%h | A=%h | G=%h | IRin=%b |
DINout=%b | Ain=%b | Gin=%b | Gout=%b | AddSub=%b | Rin=%b | Rout=%b |
R0=%h | R1=%h | R2=%h | R3=%h | R4=%h | R5=%h | R6=%h | R7=%h | Xreg=
%b | Yreg=%b | Sel=%b",
$time, Clock, Resetn, Run, Done, Tstep_Q, IR, BusWires, Sum, A,
G,
IRin, DINout, Ain, Gin, Gout, AddSub,
Rin, Rout,
R0, R1, R2, R3, R4, R5, R6, R7,
Xreg, Yreg, Sel);
end

initial begin
// Reset
Resetn = 0; Run = 0; DIN = 0;
#10 Resetn = 1;

// Test mvi R0, #5


DIN = 16'h101c; // 001_000_000_0000101;
Run = 1;
#10 Run = 0;
wait(Done);
#20;

// Test mvi R1, #3


DIN = 16'h32ff; // b001_001_000_0000011;
Run = 1;
#10 Run = 0;
wait(Done);
#20;

// Test add R0, R1


DIN = 16'h52ff; // b010_000_001_0000000;
Run = 1;
#10 Run = 0;
wait(Done);
#20;

// Test sub R0, R1


DIN = 16'h6200; //b011_000_001_0000000;
Run = 1;
#10 Run = 0;
wait(Done);
#20;

// Test mv R2, R0
DIN = 16'h0800;// b000_010_000_0000000;
Run = 1;
#10 Run = 0;
wait(Done);
#20;

$stop;
end
endmodule

P2
//part 2 top module
//加上外部存储器的处理器

//引脚说明:
//--------------------------------------------------------
// SW17-Run KEY0-Resetn KEY1-MClock
// KEY2-PClock LEDR15-0-BusWires LEDR17-Done

module part2(
input [2:0] KEY,
input [17:17] SW,
output [17:0] LEDR
);

wire Done,Resetn,PClock,MClock,Run;
wire [15:0] DIN,BusWires;
wire [4:0] pc; //计数输出,srom 的地址 0-31

assign Resetn=KEY[0];
assign PClock=KEY[0]; //processor 的时钟
assign MClock=KEY[2]; //srom 的时钟
assign Run=SW[17];

proc m0(DIN,Resetn,PClock,Run,Done,Buswires);
assign LEDR[15:0] =BusWires;
assign LEDR[17]=Done;

sromlpm m1(pc,MClock,DIN);
count5 m2(Resetn,MClock,pc);

endmodule

//count5
module count5(Resetn,Clock,Q);
input Resetn,Clock;
output reg [4:0] Q;

always @(posedge Clock)


if(Resetn==0)
Q<=5'b0;
else
Q<=Q+1'b1;
endmodule

Part2 có Debounce

module part2 (
input CLOCK_50, // Clock hệ thống
input [1:0] KEY, // Nút nhấn
input [9:0] SW, // Switch
output [9:0] LEDR, // LED hiển thị
output [15:0] DIN_out, // Dữ liệu từ bộ nhớ
output [4:0] pc_out // Địa chỉ lệnh hiện tại
);
wire Done, Resetn, Run;
wire MClock_raw, PClock_raw;
wire MClock_debounced, PClock_debounced;
reg MClock_prev, PClock_prev;
wire MClock_pulse, PClock_pulse;
wire [15:0] DIN;
wire [4:0] pc;

assign Resetn = SW[0];


assign Run = SW[9];
assign MClock_raw = KEY[0];
assign PClock_raw = KEY[1];

// Chống dính phím


debounce db_mclock (
.clk(CLOCK_50),
.btn_in(MClock_raw),
.btn_out(MClock_debounced)
);

debounce db_pclock (
.clk(CLOCK_50),
.btn_in(PClock_raw),
.btn_out(PClock_debounced)
);

// Phát hiện cạnh lên để tạo xung clock


always @(posedge CLOCK_50) begin
MClock_prev <= MClock_debounced;
PClock_prev <= PClock_debounced;
end

assign MClock_pulse = MClock_debounced & ~MClock_prev;


assign PClock_pulse = PClock_debounced & ~PClock_prev;

// Instantiate processor
proc U1 (
.DIN(DIN),
.Resetn(Resetn),
.PClock(PClock_pulse),
.Run(Run),
.Done(Done)
);

// Instantiate instruction memory


inst_mem U2 (
.address(pc),
.clock(MClock_pulse),
.q(DIN)
);

// Instantiate program counter


count5 U3 (
.Resetn(Resetn),
.Clock(MClock_pulse),
.Q(pc)
);

// Output assignments
assign LEDR[9] = Run;
assign LEDR[0] = Done;
assign LEDR[8:4] = pc;
assign LEDR[1] = DIN[0];
assign LEDR[3:2] = 2'b00;

assign DIN_out = DIN;


assign pc_out = pc;

endmodule

You might also like