verilog實現16位五級流水線的CPU帶Hazard沖突處理


verilog實現16位五級流水線的CPU帶Hazard沖突處理

該文是基於博主之前一篇博客http://www.cnblogs.com/wsine/p/4292869.html所增加的Hazard處理,相同的內容就不重復寫了,可點擊鏈接查看之前的博客。

CPU設計

該處理器的五級流水線設計:
類似於MIPS體系架構依據流水線結構設計。只要CPU從緩存中獲取數據,那么執行每條MIPS指令就被分成五個流水階段,並且每個階段占用固定的時間,通常是只耗費一個處理器時鍾周期。

處理器在設計時,將處理器的執行階段划分為以下五個階段:

  1. IF: Instruction Fetch,取指。從指令緩存(I-Cache)中獲取下一條指令。
  2. ID:Instruction Decode(Read Register),譯碼(讀寄存器)。翻譯指令,識別操作碼和操作數,從寄存器堆中讀取數據到ALU輸入寄存器。
  3. EX(ALU):Execute,執行(算術/邏輯運算)。在一個時鍾周期內,完成算術或邏輯操作。注意,浮點算術運算和整數乘除運算不能在一個時鍾周期內完成。
  4. MEM:Memory Access,內存數據讀或者寫。在該階段,指令可以從數據緩存(D-Cache)中讀/寫內存變量。平均來說,大約四分之三的指令在這一階段沒有執行任何操作,為每條指令分配這個階段是為了保證同一時刻不會有兩條指令都訪問數據緩存。
  5. WB:Write Back,寫回。操作完成后,將計算結果從ALU輸出寄存器寫回到通用寄存器中。

該CPU用到的指令集,16位8個通用寄存器

CPUregister

該CPU的全部指令一覽

Op1
Op2
Op3

該CPU的系統框圖

BlockDiagram

設計思路:(部分代碼太長處理為偽代碼)

  • CPU Control

時序邏輯,表示CPU當前狀態,有兩個枚舉值exec和idle,分別是正在運行和空閑兩種狀態

CPU Control

  • Instruction Fetch

時序邏輯,每一個上升沿從Instruction Memory中根據地址pc取出一條指令,LOAD指令需要根據不同的指令從當前CPU運算中特定位置讀取;Branch指令及其標志位為true則Flush掉一條指令;跳轉指令則直接跳轉並處理pc值延后一個周期的情況,其余情況直接讀取下一條指令

IF1
IF2
IF3

  • Instruction Decode (以reg_A為例子)

時序邏輯,根據不同的指令,從通用寄存器中取出相應的值出來作運算或者存儲到Data Memory中;如果為Branch指令且標志位為true則需要Flush掉當前內容;否則如果沖突出現,則需要根據不同的運算指令從不同的地方取出內容

ID1
ID2
ID3
ID4

  • Execute

時序邏輯,根據不同的運算指令作不同的運算;如果為存儲指令則直接轉移到下一級寄存器,並將寫入指令標記為true;如果為其余指令,則保持當前內容不變

EX

  • ALU

組合邏輯,根據不同的指令進行不同的運算,得注意SLA和SRA兩條指令在verilog里面的做法。同時注意進位操作的處理。詳細看代碼。

ALU

  • Memory Access

時序邏輯,只有當LOAD指令需要從Data Memory里面取出內容,其余情況把reg_C傳遞給reg_C1即可。cf進位標志在此階段更新。

MEM

  • Write Back

時序邏輯,對需要寫回到寄存器的指令把運算結果寫回到寄存器中,其余情況只需讓寄存器保持不變

WB

  • Instruction Memory

組合邏輯,根據地址的讀入,輸出一條指令

IM

  • Data Memory

讀取Data是組合邏輯,根據地址直接讀取一條指令輸出。
寫入Data是時序邏輯,每一個周期可能會進行一次寫入,根據dw信號進行寫入,Memory的時鍾頻率需要比CPU的時鍾快。

DM

CPU仿真測試

Testbench內容

Testbench

在test中,通過每隔5個ns,時鍾取反一次,CPU從button每20個ns進行一次反轉即時鍾周期為20ns,Memory時鍾的設置為三個clk即15個ns反轉一次,通過輸出用到的通用寄存器和用到的data memory里面的變量來觀察整個CPU的流程結果,測試CPU是否正確工作。以及觀察仿真流程的變化過程測試CPU是否正常工作。

Instruction Memory:

Instructino1
Instructino2

下面結果用16進制表示,括號內為10進制
指令0:gr1原本初始化時為0,把gr1加上一個立即數AB,gr1為00AB
指令1:gr2原本初始化時為0,把gr2加上一個高八位3C,gr2為3C00
指令2:從gr1和gr2中取值相加,結果保存在gr3中,gr3應為3CAB
指令3:把gr3的值保存到data memory中的dm0,dm0為3CAB
指令4:gr1的值為00AB,加上一個立即數11,gr1為00BC
指令5:gr2的值為3C00,加上一個高八位立即數11,gr2為4D00
指令6:從gr1和gr2中取值相加,結果保存在gr3中,gr3應為4DBC
指令7:把gr3的值保存到data memory中的dm1,dm1為4DBC
指令8:從dm0中取值到gr1中,gr1為3CAB
指令9:從dm1中取值到gr2中,gr2為4DBC
指令10:從gr2和gr1中取值相減,結果保存在gr3中,gr3應為1111
指令11:把gr3的值保存到data memory中的dm2,dm2為1111
指令12:跳轉指令,PC跳轉到第16條指令
指令13:該指令不被執行,如gr1中出現3D55則出錯
指令14:該指令不被執行,如gr1中出現3D55則出錯
指令15:該指令不被執行,如gr1中出現3D55則出錯
指令16:gr4原本初始化時為0,把gr4加上一個立即數14,gr4為0014(20)
指令17:CMP指令讓兩個相同的值相減讓標志位 zf = 1
指令18:zf = 1, 跳轉到gr4 + 2 = 22的指令
指令19:該指令不被執行,如gr1中出現3C83則出錯
指令20:該指令不被執行,如gr1中出現3C83則出錯
指令21:該指令不被執行,如gr1中出現3C83則出錯
指令22:立即數加法,gr1 + AA = 3D55,測試跳轉后流水線繼續正常工作
指令23:CMP指令讓一個小的數值減去一個大的數值,讓標志位 nf = 1
指令24:nf = 1, 不跳轉 !
指令25:立即數減法,對象是gr1,gr1 – AA = 3CAB
指令26:立即數加法,對象是gr1,gr1 + AA = 3D55
指令27:立即數減法,對象是gr1,gr1 – AA = 3CAB
指令28:空白指令,僅僅是留空,驗收時補充指令用的
指令29:空白指令,僅僅是留空,驗收時補充指令用的
指令30:跳轉指令至40
指令40:終止指令

仿真結果

re1
re2

結果分析

  1. 指令0~3,測試立即數加法和加法,計算00AB+3C00,得到3CAB存儲在dm0上。此處有Data Hazard的產生,ADD指令取gr1和gr2的時候,ADDI和LDIH指令都還沒有到達WB指令,因此要提前從結果取出。而結果顯示dm0的結果為3CAB正確。√
  2. 指令4~7,測試立即數加法和加法,計算00BC+4D00,得到4DBC存儲在dm1上。此處有Data Hazard的產生,ADD指令取gr1和gr2的時候,ADDI和LDIH指令都還沒有到達WB指令,因此要提前從結果取出。而結果顯示dm1的結果為4DBC正確。√
  3. 指令8~11,連續兩個LOAD指令,LOAD從Data Memory里面取的值還沒回到通用寄存器中,下一周期的SUB指令就需要從寄存器中取出相應的值,因此產生Hazard,但沒辦法Data Forward,所以用Stall的方法讓下一指令延后一個周期。結果gr3和dm2得到1111正確。 √
  4. 指令12~16,測試跳轉指令,PC值從12跳轉到16,從結果來看JUMP對應在ID階段的時候,下一條指令就會產生無關指令,需要Flush掉,因此指令13無效。從結果來看,PC值的變化正確,gr1的值也沒有變為3D55 。√
  5. 指令17~22,測試分支指令且需要跳轉,ZF標志位置為1,分支指令需要跳轉,且后續三條指令都需要被跳過,然后執行gr1 = 3D55 。結果顯示PC值的跳轉從20到22是因為跳轉成立與否在exe階段判斷,如不跳轉則不能Flush掉后續指令的內容。從結果來看,gr1沒有變成3CAB,且PC結果正確√
  6. 指令23~25,測試分支指令且不需要跳轉,CMP指令讓NF的值為1,BNN指令則不需要跳轉,后續的運算指令沒有被Flush掉,結果正確。√
  7. 指令25~27,連續對gr1這個寄存器取值運算並存儲回gr1中,結果顯示gr1連續在3CAB和3D55之間變化,結果正確,Data Hazard二次驗證。√
  8. 最后HALT指令讓整個CPU停止,由於需要到達WB階段才執行,所以有后續的PC=41,但是指令內容都被處理為空,不會對CPU造成影響,結果正確。√

由於是基於上一篇博客的5級流水線的基礎上加入Hazard沖突處理,因此這次沒有測試各條指令的運算結果是否正確,運算結果的正確性在上一篇博客中已經保證了。這次的測試內容是Data Hazard, Control Hazard, Stall, Branch true, Branch false, halt全部會產生Hazard的情況,結果和預期結果相符。

補充說明:
結果中出現兩個PC = 6,三個PC = 10,兩個PC = 16的情況,是由於ISE中的檢測機制$monitor函數產生的,只要有值變化就會多輸出一條,由於Memory的時鍾頻率比CPU的時鍾頻率高,因此Memory的變化先於CPU里面的,所以多輸出一條,后面的情況類似。實際情況為一個PC = 6,兩個PC = 10,一個PC = 16,其中兩個PC = 10的情況是LOAD指令產生的Stall,這是正確的。附仿真波形圖(較難看清):

fangzhen

三個實用測試

Pro13
Pro14
Pro15

一些感言
剛開始做的時候對Hazard的情況不是很理解,原本以為只需要判斷指令的操作數域是否發生沖突就算做完Data Hazard的沖突處理,就像PPT上面的圖指示的一樣。

ppt

但是自己開始做了之后就發現並不是這樣的,指令的類型很多,例如運算指令,比較指令,分支指令,跳轉指令,存儲指令,讀取指令,單純判斷操作數域的沖突是不足以判斷是否產生Hazard的,因為有些指令時立即數也可能和gr寄存器的編號相同。所以需要連同op域一同比較。
個人對Hazard的理解是,指令都是每一個時鍾周期下來流水線往前流動一級,但是一次完整的周期包括讀取指令、判斷指令、運算指令、存儲指令、回寫指令這五個周期。Data Hazard是指前一周期的指令還沒到達WB回寫寄存器這一階段,后一周期就需要在ID判斷指令階段讀取相應寄存器,因此需要把Data Forwarding操作,也就是優先把運算完成的內容取出來;Stall是針對LOAD指令的特殊操作,LOAD只能在MEM階段才能得到相應的內容,如果下一周期的指令想要Data是不能Forwarding得到的,只能通過延后一周期才能配合Data Forwarding得到相應的內容;Flush是指分支和跳轉指令需要到達EX階段才能知道標志位Flag的判斷是否應該跳轉,如果需要跳轉,則需要把后兩個周期讀進來的指令沖掉,否則會對結果有無關的影響;如果不需要Flush,則流水線繼續往前流動即可。

完整代碼

CPU.v

`timescale 1ns / 1ps

module CPU(
	input clk,
	input enable,
	input reset,
	input [3:0] SW,
	input start,
	input button,
	output [6:0] light,
	output [3:0] en
    );

	wire PCPU_clk;
	wire MEM_clk;
	wire LIGHT_clk;
	
	wire [15:0] d_datain;
	wire [15:0] i_datain;
	wire [3:0] select_y;
	wire [7:0] d_addr;
	wire [15:0] d_dataout;
	wire d_we;
	wire [7:0] i_addr;
	wire [15:0] y;
	
	clk_div getMEMclk(
		.orgin_clk(clk),
		.reset(reset),
		//.div(16'b0100_0000_0000_0000),
		.div(16'b0000_0000_0000_0001),
		.div_clk(MEM_clk)
	);
	
	clk_div getLIGHTclk(
		.orgin_clk(clk),
		.reset(reset),
		.div(16'b0010_0000_0000_0000),
		.div_clk(LIGHT_clk)
	);
	
	PCPUcontroller PCPUctrl(
		.myclk(clk),
		.button(button),
		.reset(reset),
		.sense(PCPU_clk)
	);
	
	PCPU pcpu(
		.clock(PCPU_clk),
		.enable(enable),
		.reset(reset),
		.start(start),
		.d_datain(d_datain),
		.i_datain(i_datain),
		.select_y(SW),
		.d_addr(d_addr),
		.d_dataout(d_dataout),
		.d_we(d_we),
		.i_addr(i_addr),
		.y(y)
	);
	
	I_mem i_mem(
		.mem_clk(MEM_clk),
		.addr(i_addr),
		.rdata(i_datain)
	);
	
	D_mem d_mem(
		.mem_clk(MEM_clk),
		.dwe(d_we),
		.addr(d_addr),
		.wdata(d_dataout),
		.rdata(d_datain)
	);
	
	light_show show_light(
		.light_clk(LIGHT_clk),
		.reset(reset),
		.y(y),
		.light(light),
		.en(en)
	);

endmodule

clk_div.v

`timescale 1ns / 1ps

module clk_div(
	input orgin_clk,
	input reset,
	input [15:0] div,
	output reg div_clk
    );
	
	reg [15:0] count;
	
	always@(posedge orgin_clk or posedge reset)
	begin
		if(reset)
		begin
			div_clk <= 0;
			count <= 0;
		end
		else
		begin
			if(count == div)
			begin
				div_clk <= ~div_clk;
				count <= 0;
			end
			else
				count <= count + 1'b1;
		end
	end


endmodule

D_mem.v

`timescale 1ns / 1ps
`include"headfile.v"

module D_mem(
	input mem_clk,
	input dwe,
	input [7:0] addr,
	input [15:0] wdata,
	output wire [15:0] rdata
    );
	
	reg [15:0] d_mem [255:0];
	assign rdata = d_mem[addr];
	
	always@(posedge mem_clk)
	begin
			if(dwe)
				d_mem[addr] <= wdata;
	end

	//Test by me
	/*initial begin//初始化時全為0
		d_mem[0] = 16'b0000000000000000;
		d_mem[1] = 16'b0000000000000000;
		d_mem[2] = 16'b0000000000000000;
		d_mem[3] = 16'b0000000000000000;
		d_mem[4] = 16'b0000000000000000;
		d_mem[5] = 16'b0000000000000000;
		d_mem[6] = 16'b0000000000000000;
		d_mem[7] = 16'b0000000000000000;
		d_mem[8] = 16'b0000000000000000;
		d_mem[9] = 16'b0000000000000000;
		d_mem[10] = 16'b0000000000000000;
		d_mem[11] = 16'b0000000000000000;
		d_mem[12] = 16'b0000000000000000;
		d_mem[13] = 16'b0000000000000000;
		d_mem[14] = 16'b0000000000000000;
		d_mem[15] = 16'b0000000000000000;
		d_mem[16] = 16'b0000000000000000;
		d_mem[17] = 16'b0000000000000000;
		d_mem[18] = 16'b0000000000000000;
		d_mem[19] = 16'b0000000000000000;
	end*/
	
	// Bubble Test
	/*initial begin
		d_mem[0] = 16'h000a;
		d_mem[1] = 16'h0004;
		d_mem[2] = 16'h0005;
		d_mem[3] = 16'h2369;
		d_mem[4] = 16'h69c3;
		d_mem[5] = 16'h0060;
		d_mem[6] = 16'h0fff;
		d_mem[7] = 16'h5555;
		d_mem[8] = 16'h6152;
		d_mem[9] = 16'h1057;
		d_mem[10] = 16'h2895;
	end*/
	
	// GCD Test
	/*initial begin
		d_mem[0] = 16'h0000;
		d_mem[1] = 16'h0020;
		d_mem[2] = 16'h0018;
		d_mem[3] = 16'h0000;
		d_mem[4] = 16'h0000;
		d_mem[5] = 16'h0000;
		d_mem[6] = 16'h0000;
		d_mem[7] = 16'h0000;
		d_mem[8] = 16'h0000;
		d_mem[9] = 16'h0000;
		d_mem[10] = 16'h0000;
	end*/
	
	// Sort Test
	/*initial begin
		d_mem[0] = 16'h000a;
		d_mem[1] = 16'h0009;
		d_mem[2] = 16'h0006;
		d_mem[3] = 16'h0005;
		d_mem[4] = 16'h0001;
		d_mem[5] = 16'h0004;
		d_mem[6] = 16'h0003;
		d_mem[7] = 16'h0011;
		d_mem[8] = 16'h0000;
		d_mem[9] = 16'h0000;
		d_mem[10] = 16'h0000;
	end*/
	
	// ADD64 Test
	initial begin
		d_mem[0] <= 16'hfffe;
		d_mem[1] <= 16'hfffe;
		d_mem[2] <= 16'hfffe;
		d_mem[3] <= 16'h0000;
		d_mem[4] <= 16'hffff;
		d_mem[5] <= 16'hffff;
		d_mem[6] <= 16'hffff;
		d_mem[7] <= 16'h0000;
		d_mem[8] = 16'h0000;
		d_mem[9] = 16'h0000;
		d_mem[10] = 16'h0000;
	end
	
	// Test All
	/*initial begin
		d_mem[0] <= 16'hfffd;
		d_mem[1] <= 16'h0004;
		d_mem[2] <= 16'h0005;
		d_mem[3] <= 16'hc369;
		d_mem[4] <= 16'h69c3;
		d_mem[5] <= 16'h0041;
		d_mem[6] <= 16'hffff;
		d_mem[7] <= 16'h0001;
	end*/

endmodule

headfile.v

`ifndef HEADFILE_H_

//State for CPU
`define	idle		1'b0
`define	exec		1'b1

//Data transfer & Arithmetic
`define  NOP		5'b00000
`define  HALT		5'b00001
`define  LOAD		5'b00010
`define  STORE		5'b00011
`define  LDIH		5'b10000
`define  ADD		5'b01000
`define	ADDI		5'b01001
`define	ADDC		5'b10001
`define	CMP		5'b01100

//Logical / shift
`define	AND		5'b01101
`define	SLL		5'b00100
`define	SLA		5'b00101

//Control
`define	JUMP		5'b11000
`define	JMPR		5'b11001
`define	BZ			5'b11010
`define	BNZ		5'b11011
`define	BN			5'b11100
`define	BC			5'b11110

//Add by myself
`define	SUB   	5'b01010
`define 	SUBI  	5'b01011
`define 	SUBC  	5'b10010
`define 	OR    	5'b01110
`define 	XOR   	5'b01111
`define 	SRL   	5'b00110
`define 	SRA   	5'b00111
`define 	BNN   	5'b11101
`define 	BNC   	5'b11111

//gr
`define gr0 3'b000
`define gr1 3'b001
`define gr2 3'b010
`define gr3 3'b011
`define gr4 3'b100
`define gr5 3'b101
`define gr6 3'b110
`define gr7 3'b111

`endif

I_mem.v

`timescale 1ns / 1ps
`include"headfile.v"

module I_mem(
	input mem_clk,
	input [7:0] addr,
	output wire [15:0] rdata
    );

	reg [15:0] i_mem [255:0];
	assign rdata = i_mem[addr];
	
	// Test by me
	/*initial begin
		i_mem[0] <= {`ADDI, `gr1, 4'b1010, 4'b1011}; // gr1 = 00AB;
		i_mem[1] <= {`LDIH, `gr2, 4'b0011, 4'b1100}; // gr2 = 3C00;
		i_mem[2] <= {`ADD, `gr3, 1'b0, `gr1, 1'b0, `gr2}; // gr3 = 3CAB;
		i_mem[3] <= {`STORE, `gr3, 1'b0, `gr0, 4'b0000}; // dm0 = 3CAB;
		i_mem[4] <= {`ADDI, `gr1, 4'b0001, 4'b0001}; // gr1 = 00BC;
		i_mem[5] <= {`LDIH, `gr2, 4'b0001, 4'b0001}; // gr2 = 4D00;
		i_mem[6] <= {`ADD, `gr3, 1'b0, `gr1, 1'b0, `gr2}; // gr3 = 4DBC;
		i_mem[7] <= {`STORE, `gr3, 1'b0, `gr0, 4'b0001}; // dm1 = 4DBC;
		i_mem[8] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0000}; // gr1 = 3CAB;
		i_mem[9] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0001}; // gr2 = 4DBC;
		i_mem[10] <= {`SUB, `gr3, 1'b0, `gr2, 1'b0, `gr1}; // gr3 = 1111;
		i_mem[11] <= {`STORE, `gr3, 1'b0, `gr0, 4'b0010}; // dm2 = 1111;
		i_mem[12] <= {`JUMP, 3'b000, 4'b0001, 4'b0000}; // Jump to 16
		i_mem[13] <= {`ADDI, `gr1, 4'b1010, 4'b1011};//Not Used
		i_mem[14] <= {`ADDI, `gr1, 4'b1010, 4'b1011};//Not Used
		i_mem[15] <= {`ADDI, `gr1, 4'b1010, 4'b1011};//Not Used
		i_mem[16] <= {`ADDI, `gr4, 4'b0001, 4'b0100}; // gr4 = 20(0014);
		i_mem[17] <= {`CMP, 3'b000, 1'b0, `gr1, 1'b0, `gr1}; // let zf = 1
		i_mem[18] <= {`BZ, `gr4, 4'b0000, 4'b0010}; // Branch true to 22
		i_mem[19] <= {`SUBI, `gr1, 4'b0010, 4'b1000};//Not Used
		i_mem[20] <= {`SUBI, `gr1, 4'b0010, 4'b1000};//Not Used
		i_mem[21] <= {`SUBI, `gr1, 4'b0010, 4'b1000};//Not Used
		i_mem[22] <= {`ADDI, `gr1, 4'b1010, 4'b1010}; // gr1 = 3D55;
		i_mem[23] <= {`CMP, 3'b000, 1'b0, `gr1, 1'b0, `gr2}; // let nf = 1
		i_mem[24] <= {`BNN, `gr4, 4'b0000, 4'b0101}; // Branch false to 25
		i_mem[25] <= {`SUBI, `gr1, 4'b1010, 4'b1010}; // gr1 = 3CAB;
		i_mem[26] <= {`ADDI, `gr1, 4'b1010, 4'b1010}; // gr1 = 3D55;
		i_mem[27] <= {`SUBI, `gr1, 4'b1010, 4'b1010}; // gr1 = 3CAB;
		i_mem[28] <= {`NOP, `gr1, 4'b1010, 4'b1010};
		i_mem[29] <= {`NOP, `gr1, 4'b1010, 4'b1010};
		i_mem[30] <= {`JUMP, 3'b000, 4'b0010, 4'b1000}; // Jump to 40
		i_mem[40] <= {`HALT, 11'b000_0000_0000}; // Stop
	end*/
	
	// Bubble Test
	/*initial begin
		i_mem[0] <= {`LOAD, `gr3, 4'b0000, 4'b0000};
		i_mem[1] <= {`SUBI, `gr3, 4'b0000, 4'b0010};
		i_mem[2] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr0};
		i_mem[3] <= {`ADD, `gr2, 1'b0, `gr3, 1'b0, `gr0}; // loop1
		i_mem[4] <= {`LOAD, `gr4, 1'b0, `gr2, 4'b0001}; // loop2
		i_mem[5] <= {`LOAD, `gr5, 1'b0, `gr2, 4'b0010};
		i_mem[6] <= {`CMP, 3'b000, 1'b0, `gr5, 1'b0, `gr4};
		i_mem[7] <= {`BN, `gr0, 4'b0000, 4'b1010};// Jump to 10 or not
		i_mem[8] <= {`STORE, `gr4, 1'b0, `gr2, 4'b0010};
		i_mem[9] <= {`STORE, `gr5, 1'b0, `gr2, 4'b0001};
		i_mem[10] <= {`SUBI, `gr2, 4'b0000, 4'b0001};     //bunkisaki
		i_mem[11] <= {`CMP, 3'b000, 1'b0, `gr2, 1'b0, `gr1};
		i_mem[12] <= {`BNN, `gr0, 4'b0000, 4'b0100};//Jump to 4 or not
		i_mem[13] <= {`ADDI, `gr1, 4'b0000, 4'b0001};
		i_mem[14] <= {`CMP, 3'b000, 1'b0, `gr3, 1'b0, `gr1};
		i_mem[15] <= {`BNN, `gr0, 4'b0000, 4'b0011};//Jump to 3 or not
		i_mem[16] <= {`HALT, 11'b000_0000_0000};
	end*/
	
	// Gcd Test
	/*initial begin
		i_mem[0] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001}; //GCM
		i_mem[1] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010}; 
		i_mem[2] <= {`ADD, `gr3, 1'b0, `gr0, 1'b0, `gr1}; //(1)
		i_mem[3] <= {`SUB, `gr1, 1'b0, `gr1, 1'b0, `gr2};
		i_mem[4] <= {`BZ, `gr0, 4'b0000, 4'b1001}; //jump to (2)
		i_mem[5] <= {`BNN, `gr0, 4'b0000, 4'b0010}; //jump to (1)
		i_mem[6] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr2};
		i_mem[7] <= {`ADD, `gr2, 1'b0, `gr0, 1'b0, `gr3};
		i_mem[8] <= {`JUMP, 3'b000, 4'b0000, 4'b0010}; //jump to (1)
		i_mem[9] <= {`STORE, `gr2, 1'b0, `gr0, 4'b0011}; //(2)
		i_mem[10] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001};  //LCM
		i_mem[11] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010};
		i_mem[12] <= {`ADDI, `gr4, 4'b0000, 4'b0001}; //(3)
		i_mem[13] <= {`SUB, `gr2, 1'b0, `gr2, 1'b0, `gr3};
		i_mem[14] <= {`BZ, `gr0, 4'b0001, 4'b0000}; //jump to (4)
		i_mem[15] <= {`JUMP, 3'b000, 4'b0000, 4'b1100}; //jump to (3)
		i_mem[16] <= {`SUBI, `gr4, 4'b0000, 4'b0001}; //(4)
		i_mem[17] <= {`BN, `gr0, 4'b0001, 4'b0100}; //jump to (5)
		i_mem[18] <= {`ADD, `gr5, 1'b0, `gr5, 1'b0, `gr1};
		i_mem[19] <= {`JUMP, 3'b000, 4'b0001, 4'b0000}; //jump to (4)
		i_mem[20] <= {`STORE, `gr5, 1'b0, `gr0, 4'b0100}; //(5)
		i_mem[21] <= {`HALT, 11'b000_0000_0000};
	end*/
	
	// Sort Test
	/*initial begin
		i_mem[0] <= {`ADDI, `gr1, 4'b0000, 4'b1001};// init
		i_mem[1] <= {`ADDI, `gr2, 4'b0000, 4'b1001};
		i_mem[2] <= {`JUMP, 3'b000, 8'b00000101};// jump to START
		i_mem[3] <= {`SUBI, `gr1, 4'b0000, 4'b0001};// NEW_ROUND
		i_mem[4] <= {`BZ, `gr7, 4'b0000, 4'b0001};// jump to END
		i_mem[5] <= {`LOAD, `gr3, 1'b0, `gr0, 4'b0000};// START
		i_mem[6] <= {`LOAD, `gr4, 1'b0, `gr0, 4'b0001};
		i_mem[7] <= {`CMP, 3'b000, 1'b0, `gr3, 1'b0, `gr4};
		i_mem[8] <= {`BN, `gr7, 8'b00001011};// jump to NO_OP
		i_mem[9] <= {`STORE, `gr3, 1'b0, `gr0, 4'b0001};// store back
		i_mem[10] <= {`STORE, `gr4, 1'b0, `gr0, 4'b0000};
		i_mem[11] <= {`ADDI, `gr0, 4'b0000, 4'b0001}; // NO_OP
		i_mem[12] <= {`CMP, 3'b000, 1'b0, `gr0, 1'b0, `gr2};
		i_mem[13] <= {`BN, `gr7, 8'b00010001}; // jump to CONTINUE
		i_mem[14] <= {`SUBI, `gr2, 8'b00000001}; // UPDATE
		i_mem[15] <= {`SUB, `gr0, 1'b0, `gr0, 1'b0, `gr0};
		i_mem[16] <= {`JUMP, 3'b000, 8'b00000011};// jump to NEW_ROUND
		i_mem[17] <= {`JUMP, 3'b000, 8'b00000101};// jump to START #CONTINUE#
		i_mem[18] <= {`HALT, 11'b000_0000_0000};
	end*/
	
	// 64Add Test
	initial begin
		i_mem[0] <= {`ADDI, `gr4, 4'b0000, 4'b0100};
		i_mem[1] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0000};
		i_mem[2] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0100};
		i_mem[3] <= {`ADD, `gr3, 1'b0, `gr1, 1'b0, `gr2};
		i_mem[4] <= {`BNC, `gr5, 4'b0000, 4'b0110};//bnc to 6 11111 101 0000 0110
		i_mem[5] <= {`ADDI, `gr6, 4'b0000, 4'b0001};
		i_mem[6] <= {`ADD, `gr3, 1'b0, `gr3, 1'b0, `gr7};
		i_mem[7] <= {`BNC, `gr5, 4'b0000, 4'b1011};//bnc to 11 // 11111 101 0000 1011
		i_mem[8] <= {`SUBI, `gr6, 4'b0000, 4'b0000};                               // {`}
		i_mem[9] <= {`BNZ, `gr5, 4'b0000, 4'b1011} ;//bnz to 11        // 11011 101 0000 1011               // {`BNZ, }
		i_mem[10] <= {`ADDI, `gr6, 4'b0000, 4'b0001};  			//01001'110'0000'0001 // {`ADDC, `gr6, 1'b0, `gr0, 1'b0, `gr1}
		i_mem[11] <= {`SUB, `gr7, 1'b0, `gr7, 1'b0, `gr7};	  			//01010'111'0111'0111 // {`SUB, `gr7, 1'b0, `gr7, 1'b0, `gr7}
		i_mem[12] <= {`ADD, `gr7, 1'b0, `gr7, 1'b0, `gr6};   			//01000'111'0111'0110 // {`ADD, `gr7, 1'b0, `gr7, 1'b0, `gr6}
		i_mem[13] <= {`SUB, `gr6, 1'b0, `gr6, 1'b0, `gr6};	  			//01010'110'0110'0110 // {`SUB, `gr6, 1'b0, `gr6, 1'b0, `gr6}
		i_mem[14] <= {`STORE, `gr3, 4'b0000, 4'b1000};	  			//00011'011'0000'1000 // {`STORE, `gr3, 4'b0000, 4'b1000}
		i_mem[15] <= {`ADDI, `gr0, 4'b0000, 4'b0001};		  			//01001'000'0000'0001 // {`ADDC, `gr0, 1'b0, `gr0, 1'b0, `gr1}
		i_mem[16] <= {`CMP, 3'b000, 1'b0, `gr0, 1'b0, `gr4};   			//01100'000'0000'0100 // {`CMP, 3'b000, 1'b0, `gr0, 1'b0, `gr4}
		i_mem[17] <= {`BN, `gr5, 4'b0000, 4'b0001};//bn to 1 //11100'101'0000'0001 // {`BZ, `gr5, 4'b0000, 4'b0001}
		i_mem[18] <= {`HALT, 11'b000_0000_0000};				//00001'000'0000'0000 // {`HALT, 11'b000_0000_0000};
	end
	
	// Test All
	/*initial begin
		i_mem[0]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h10 for store address
		i_mem[1]={`LDIH,`gr1,4'b1011,4'b0110};        // test for LDIH  gr1<="16'hb600"
		i_mem[2]={`STORE,`gr1,1'b0,`gr7,4'h0};        // store to mem10	
		i_mem[3]={`LOAD,`gr1,1'b0,`gr0,4'h0};         // gr1 <= fffd 
		i_mem[4]={`LOAD,`gr2,1'b0,`gr0,4'h1};         // gr2 <= 4
		i_mem[5]={`ADDC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= fffd + 4 + cf(=0) = 1, cf<=1
		i_mem[6]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem11		
		i_mem[7]={`ADDC,`gr3,1'b0,`gr0,1'b0,`gr2};    // gr3 <= 0 + 4 + cf(=1) = 5, cf<=0
		i_mem[8]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem12
		i_mem[9]={`LOAD,`gr1,1'b0,`gr0,4'h2};          // gr1 <= 5 
		i_mem[10]={`SUBC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= 5 - 4 + cf(=0) =1, cf<=0    
		i_mem[11]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem13		
		i_mem[12]={`SUB,`gr3,1'b0,`gr2,1'b0,`gr1};     // gr3 <= 4 - 5 = -1, cf<=1    
		i_mem[13]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem14		
		i_mem[14]={`SUBC,`gr3,1'b0,`gr2,1'b0,`gr1};    // gr3 <= 5 - 4 - cf(=1) =2, cf<=0 
		i_mem[15]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem15		
		i_mem[16]={`LOAD,`gr1,1'b0,`gr0,4'h3};         // gr1 <= c369
		i_mem[17]={`LOAD,`gr2,1'b0,`gr0,4'h4};         // gr2 <= 69c3		
		i_mem[18]={`AND,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 & gr2 = 4141
		i_mem[19]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem16		
		i_mem[20]={`OR,`gr3,1'b0,`gr1,1'b0,`gr2};      // gr3 <= gr1 | gr2 = ebeb
		i_mem[21]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem17		
		i_mem[22]={`XOR,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 ^ gr2 = aaaa
		i_mem[23]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem18
		i_mem[24]={`SLL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0 
		i_mem[25]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem19		
		i_mem[26]={`SLL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1 
		i_mem[27]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem1a		
		i_mem[28]={`SLL,`gr3,1'b0,`gr1,4'h4};          // gr3 <= gr1 < 8 
		i_mem[29]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem1b	
		i_mem[30]={`SLL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15 
		i_mem[31]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem1c
		i_mem[32]={`SRL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
		i_mem[33]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem1d		
		i_mem[34]={`SRL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
		i_mem[35]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem1e		
		i_mem[36]={`SRL,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
		i_mem[37]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem1f		
		i_mem[38]={`SRL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
		i_mem[39]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h20 for store address
		i_mem[40]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem20
		i_mem[41]={`SLA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0
		i_mem[42]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem21
		i_mem[43]={`SLA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1 
		i_mem[44]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem22
		i_mem[45]={`SLA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 < 8 
		i_mem[46]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem23
		i_mem[47]={`SLA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15
		i_mem[48]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem24
		i_mem[49]={`SLA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 < 0
		i_mem[50]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem25
		i_mem[51]={`SLA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 < 1
		i_mem[52]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem26
		i_mem[53]={`SLA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 < 8
		i_mem[54]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem27
		i_mem[55]={`SLA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 < 15
		i_mem[56]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem28
		i_mem[57]={`SRA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
		i_mem[58]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem29
		i_mem[59]={`SRA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
		i_mem[60]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem2a
		i_mem[61]={`SRA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
		i_mem[62]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem2b
		i_mem[63]={`SRA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
		i_mem[64]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem2c
		i_mem[65]={`SRA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 > 0
		i_mem[66]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem2d
		i_mem[67]={`SRA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 > 1
		i_mem[68]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem2e
		i_mem[69]={`SRA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 > 8
		i_mem[70]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem2f
		i_mem[71]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h30 for store address
		i_mem[72]={`SRA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 > 15
		i_mem[73]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem30		
		i_mem[74]={`LOAD,`gr1,1'b0,`gr0,4'h5};         // gr1 <= 41
		i_mem[75]={`LOAD,`gr2,1'b0,`gr0,4'h6};         // gr2 <= ffff
		i_mem[76]={`LOAD,`gr3,1'b0,`gr0,4'h7};         // gr3 <= 1
		i_mem[77]={`JUMP, 3'd0,8'h4f};                 // jump to 4f
		i_mem[78]={`STORE,`gr7,1'b0,`gr7,4'h1};        // store to mem31
		i_mem[79]={`JMPR, `gr1,8'h10};                 // jump to 41+10 = 51
		i_mem[80]={`STORE,`gr7,1'b0,`gr7,4'h2};        // store to mem32
		i_mem[81]={`ADD, `gr4,1'b0,`gr2,1'b0,`gr3};    // gr4<= ffff + 1,cf<=1
		i_mem[82]={`BNC,`gr1,8'h28};                   // if(cf==0) jump to 69
		i_mem[83]={`BC,`gr1,8'h14};                    // if(cf==1) jump to 55
		i_mem[84]={`STORE,`gr7,1'b0,`gr7,4'h3};        // store to mem33
		i_mem[85]={`ADD, `gr4,1'b0,`gr3,1'b0,`gr3};    // gr4<= 1 + 1 , cf<=0
		i_mem[86]={`BC,`gr1,8'h28};                   // if(cf==1) jump to 69
		i_mem[87]={`BNC,`gr1,8'h18};                  // if(cf==0) jump to 59
		i_mem[88]={`STORE,`gr7,1'b0,`gr7,4'h4};        // store to mem34
		i_mem[89]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr3};    // 1-1=0 , zf<=1,nf<=0
		i_mem[90]={`BNZ,`gr1,8'h28};                   // if(zf==0) jump to 69
		i_mem[91]={`BZ,`gr1,8'h1c};                    // if(zf==1) jump to 5d
		i_mem[92]={`STORE,`gr7,1'b0,`gr7,4'h5};        // store to mem35
		i_mem[93]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};    // 2-1=1 , zf<=0,nf<=0 
		i_mem[94]={`BZ,`gr1,8'h28};                    // if(zf==1) jump to 69
		i_mem[95]={`BNZ,`gr1,8'h20};                   // if(zf==0) jump to 61
		i_mem[96]={`STORE,`gr7,1'b0,`gr7,4'h6};        // store to mem36
		i_mem[97]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr4};    // 1-2=-1, nf<=1,zf<=0
		i_mem[98]={`BNN,`gr1,8'h28};                   // if(nf==0) jump to 69
		i_mem[99]={`BN,`gr1,8'h24};                    // if(nf==1) jump to 65 
		i_mem[100]={`STORE,`gr7,1'b0,`gr7,4'h7};        // store to mem37
		i_mem[101]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};    // 2-1=1, nf<=0,zf<=0
		i_mem[102]={`BN,`gr1,8'h28};                    // if(nf==1) jump to 69
		i_mem[103]={`BNN,`gr1,8'h27};                   // if(nf==0) jump to 68
		i_mem[104]={`STORE,`gr7,1'b0,`gr7,4'h8};        // store to mem38
		i_mem[105]={`HALT, 11'd0};                      // STOP
	end*/
	

endmodule

PCPU.v

`timescale 1ns / 1ps
`include"headfile.v"

module PCPU(
	input clock,
	input enable,
	input reset,
	input start,
	input [15:0] d_datain,
	input [15:0] i_datain,
	input [3:0] select_y,
	output wire [7:0] d_addr,
	output wire [15:0] d_dataout,
	output wire d_we,
	output wire [7:0] i_addr,
	output reg [15:0] y
    );

	reg state;
	reg [7:0] pc;
	reg [15:0] id_ir;
	reg [15:0] ex_ir, reg_A, reg_B, smdr;
	reg [15:0] mem_ir, reg_C, smdr1; reg dw; reg flag; reg [15:0] ALUo;reg zf, nf, cf;
	reg [15:0] wb_ir, reg_C1;
	
	reg [15:0] gr[0:7];
	
	assign d_dataout = smdr1;
	assign d_we = dw;
	assign d_addr = reg_C[7:0];
	assign i_addr = pc;
	
	/*******CPUcontrol**********************/
	reg nextstate;
	
	always@(posedge clock or posedge reset)
	begin
		if(reset)
			state <= `idle;
		else
			state <= nextstate;
	end
	
	always@(*)
	begin
		case(state)
			`idle:
				if((enable == 1'b1) && (start == 1'b1))
					nextstate <= `exec;
				else
					nextstate <= `idle;
			`exec:
				if((enable == 1'b0) || (wb_ir[15:11] == `HALT))
					nextstate <= `idle;
				else
					nextstate <= `exec;
		endcase
	end
	
	/***************************************/
	
	/****************IF*********************/
	always@(posedge clock or posedge reset)
	begin
		if(reset)
		begin
			id_ir <= 16'b0000_0000_0000_0000;
			pc <= 8'b0000_0000;
		end
		else if(state == `exec)
		begin
			/*************Hazard*******************/
			if ((id_ir[15:11]==`LOAD)
			  &&(i_datain[15:11]!=`JUMP)&&(i_datain[15:11]!=`NOP)
			  &&(i_datain[15:11]!=`HALT)&&(i_datain[15:11]!=`LOAD))
				begin
					/*********r1*********/
					if((id_ir[10:8]==i_datain[2:0])
					 &&((i_datain[15:11]==`ADD)||(i_datain[15:11]==`ADDC)
					  ||(i_datain[15:11]==`SUB)||(i_datain[15:11]==`SUBC)
					  ||(i_datain[15:11]==`CMP)||(i_datain[15:1]==`AND)
					  ||(i_datain[15:11]==`OR)||(i_datain[15:11]==`XOR)))
						begin
							pc <= pc;
							id_ir <= i_datain;
						end
					/*********r2*********/
					else if((id_ir[10:8]==i_datain[6:4])
							&&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`ADD)
							 ||(i_datain[15:11]==`ADDC)||(i_datain[15:11]==`SUB)
							 ||(i_datain[15:11]==`SUBC)||(i_datain[15:11]==`CMP)
							 ||(i_datain[15:11]==`AND)||(i_datain[15:11]==`OR)
							 ||(i_datain[15:11]==`XOR)||(i_datain[15:11]==`SLL)
							 ||(i_datain[15:11]==`SRL)||(i_datain[15:11]==`SLA)
							 ||(i_datain[15:11]==`SRA)))		//r2
						begin
							pc <= pc;
							id_ir <= i_datain;
						end
					/*********r3*********/
					else if((id_ir[10:8]==i_datain[10:8])
						   &&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`LDIH)
							 ||(i_datain[15:11]==`ADDI)||(i_datain[15:11]==`SUBI)
							 ||(i_datain[15:11]==`JMPR)||(i_datain[15:11]==`BZ)
							 ||(i_datain[15:11]==`BNZ)||(i_datain[15:11]==`BN)
							 ||(i_datain[15:11]==`BNN)||(i_datain[15:11]==`BC)
							 ||(i_datain[15:11]==`BNC)))
						begin
							pc <= pc;
							id_ir <= i_datain;
						end
					else
						begin
							pc <= pc + 1'b1;
							id_ir <= i_datain;
						end
				end
			/**************************************/
			else
			begin
				if(((ex_ir[15:11] == `BZ)  && (zf == 1'b1))
				 ||((ex_ir[15:11] == `BN)  && (nf == 1'b1))
				 ||((ex_ir[15:11] == `BC)  && (cf == 1'b1))
				 ||((ex_ir[15:11] == `BNZ) && (zf == 1'b0))
				 ||((ex_ir[15:11] == `BNN) && (nf == 1'b0))
				 ||((ex_ir[15:11] == `BNC) && (cf == 1'b0))
				 || (ex_ir[15:11] == `JMPR))
					begin pc <= ALUo[7:0]; id_ir <= {`NOP, 000_0000_0000}; end // Flush
				else if(id_ir[15:11] == `JUMP)
					begin pc <= id_ir[7:0]; id_ir <= {`NOP, 000_0000_0000}; end
				else if(id_ir[15:11] == `HALT) // STOP
					begin pc <= pc; id_ir <= id_ir; end
				else
					begin pc <= pc + 1'b1; id_ir <= i_datain; end
			end
		end
		else
		begin
			pc <= pc;
			id_ir <= id_ir;
		end
	end
	
	/***************************************/
	
	/****************ID*********************/
	always@(posedge clock or posedge reset)
	begin
		if(reset)
		begin
			ex_ir <= 16'b0000_0000_0000_0000;
			reg_A <= 16'b0000_0000_0000_0000;
			reg_B <= 16'b0000_0000_0000_0000;
			smdr <= 16'b0000_0000_0000_0000;
		end
		/********Flush*********/
		else if((state == `exec) &&
				  (((ex_ir[15:11]==`BZ)&&(zf==1'b1))
				 ||((ex_ir[15:11]==`BNZ)&&(zf==1'b0))
				 ||((ex_ir[15:11]==`BN)&&(nf==1'b1))
				 ||((ex_ir[15:11]==`BNN)&&(nf==1'b0))
				 ||((ex_ir[15:11]==`BC)&&(cf==1'b1))
				 ||((ex_ir[15:11]==`BNC)&&(nf==1'b0))
				 || (ex_ir[15:11]==`JMPR)))
				 ex_ir <= {`NOP, 000_0000_0000};
		/********Flush*********/
		else if(state == `exec)
		begin
			ex_ir <= id_ir;
			//reg_A
			/********************Hazard**********************/
			if((id_ir[15:11]==`BZ)||(id_ir[15:11]==`BNZ)
			 ||(id_ir[15:11]==`BN)||(id_ir[15:11]==`BNN)
			 ||(id_ir[15:11]==`BC)||(id_ir[15:11]==`BNC)
			 ||(id_ir[15:11]==`ADDI)||(id_ir[15:11]==`SUBI)
			 ||(id_ir[15:11]==`LDIH)||(id_ir[15:11]==`JMPR))
				begin
					if(((id_ir[15:11]==`BZ)||(id_ir[15:11]==`BNZ)
					 ||(id_ir[15:11]==`BN)||(id_ir[15:11]==`BNN)
					 ||(id_ir[15:11]==`BC)||(id_ir[15:11]==`BNC))
					 &&(id_ir[10:8]==`gr0))//分支指令,基地址為0直接到偏移量地址的不會有沖突
						begin		reg_A <= gr[id_ir[10:8]];		end
					else if((id_ir[10:8]==ex_ir[10:8])
					 &&(ex_ir[15:11]!=`NOP)&&(ex_ir[15:11]!=`HALT)
					 &&(ex_ir[15:11]!=`LOAD)&&(ex_ir[15:11]!=`CMP)
					 &&(ex_ir[15:11]!=`JUMP)
					 &&(id_ir[15:0] != ex_ir[15:0]))//該行避免LOAD產生的Stall有影響
						begin		reg_A <= ALUo;		end
					else if((id_ir[10:8]==mem_ir[10:8])
							&&(mem_ir[15:11]!=`NOP)&&(mem_ir[15:11]!=`HALT)
							&&(mem_ir[15:11]!=`CMP)&&(mem_ir[15:11]!=`JUMP))
						begin
							if(mem_ir[15:11]==`LOAD)	reg_A <= d_datain;
							else								reg_A <= reg_C;
						end
					else if((id_ir[10:8]==wb_ir[10:8])
						   &&(wb_ir[15:11]!=`NOP)&&(wb_ir[15:11]!=`HALT)
							&&(wb_ir[15:11]!=`CMP)&&(wb_ir[15:11]!=`JUMP)
							&&(id_ir[15:11] != wb_ir[15:11]))//該行避免同指令的無效位沖突
						begin		reg_A <= reg_C1;		end
					else
						begin		reg_A <= gr[id_ir[10:8]];		end	//r1
				end
			else if((id_ir[15:11]==`LOAD)||(id_ir[15:11]==`STORE)
					||(id_ir[15:11]==`ADD)||(id_ir[15:11]==`ADDC)
					||(id_ir[15:11]==`SUB)||(id_ir[15:11]==`SUBC)
					||(id_ir[15:11]==`CMP)||(id_ir[15:11]==`AND)
					||(id_ir[15:11]==`OR)||(id_ir[15:11]==`XOR)
					||(id_ir[15:11]==`SLL)||(id_ir[15:11]==`SRL)
					||(id_ir[15:11]==`SLA)||(id_ir[15:11]==`SRA))
				begin
					if((id_ir[6:4]==ex_ir[10:8])
					 &&(ex_ir[15:11]!=`NOP)&&(ex_ir[15:11]!=`HALT)
					 &&(ex_ir[15:11]!=`LOAD)&&(ex_ir[15:11]!=`CMP)
					 &&(ex_ir[15:11]!=`JUMP)
					 &&(id_ir[6:4]!=`gr0))//gr0沖突無關緊要,允許沖突
						begin		reg_A <= ALUo;		end
					else if((id_ir[6:4]==mem_ir[10:8])
							&&(mem_ir[15:11]!=`NOP)&&(mem_ir[15:11]!=`HALT)
							&&(mem_ir[15:11]!=`CMP)&&(mem_ir[15:11]!=`JUMP)
							&&(id_ir[6:4]!=`gr0))//gr0沖突無關緊要,允許沖突
						begin
							if(mem_ir[15:11]==`LOAD)	reg_A <= d_datain;
							else								reg_A <= reg_C;
						end
					else if((id_ir[6:4]==wb_ir[10:8])
							&&((wb_ir[15:11]!=`NOP)&&(wb_ir[15:11]!=`HALT)
							&&(wb_ir[15:11]!=`CMP)&&(wb_ir[15:11]!=`JUMP))
							&&(id_ir[6:4]!=`gr0))//gr0沖突無關緊要,允許沖突
						begin		reg_A <= reg_C1;		end
					else
						begin		reg_A <= gr[id_ir[6:4]];		end	//r2
				end
			else if(((mem_ir[15:11]==`BZ)&&(zf==1'b1))
					||((mem_ir[15:11]==`BNZ)&&(zf==1'b0))
					||((mem_ir[15:11]==`BN)&&(nf==1'b1))
					||((mem_ir[15:11]==`BNN)&&(nf==1'b0))
					||((mem_ir[15:11]==`BC)&&(cf==1'b1))
					||((mem_ir[15:11]==`BNC)&&(nf==1'b0))
					|| (mem_ir[15:11]==`JMPR))
				begin		reg_A <= 16'b0;		end
			else
			begin
			/***********************************************/
				if((id_ir[15:11] == `BZ)
				 ||(id_ir[15:11] == `BN)
				 ||(id_ir[15:11] == `JMPR)
				 ||(id_ir[15:11] == `BC)
				 ||(id_ir[15:11] == `BNZ)
				 ||(id_ir[15:11] == `BNN)
				 ||(id_ir[15:11] == `BNC)
				 ||(id_ir[15:11] == `ADDI)
				 ||(id_ir[15:11] == `SUBI)
				 ||(id_ir[15:11] == `LDIH))
					reg_A <= gr[(id_ir[10:8])];
				else if(id_ir[15:11] == `JUMP)
					reg_A <= 16'b0000_0000_0000_0000;
				else
					reg_A <= gr[(id_ir[6:4])];
			end
			
			//reg_B
			/********************Hazard*********************/
			if(id_ir[15:11]==`LDIH)
				begin		reg_B <= {id_ir[7:0], 8'b0000_0000};	end
			else if((id_ir[15:11]==`STORE)||(id_ir[15:11]==`LOAD)
					||(id_ir[15:11]==`SLL)||(id_ir[15:11]==`SRL)
					||(id_ir[15:11]==`SLA)||(id_ir[15:11]==`SRA))
				begin		reg_B <= {12'b0000_0000_0000, id_ir[3:0]};	end
			else if((id_ir[15:11]==`BZ)||(id_ir[15:11]==`BNZ)
					||(id_ir[15:11]==`BN)||(id_ir[15:11]==`BNN)
					||(id_ir[15:11]==`BC)||(id_ir[15:11]==`BNC)
					||(id_ir[15:11]==`ADDI)||(id_ir[15:11]==`SUBI)
					||(id_ir[15:11]==`JUMP)||(id_ir[15:11]==`JMPR))
				begin		reg_B <= {8'b0000_0000, id_ir[7:0]};	end
			else if((id_ir[15:11]==`ADD)||(id_ir[15:11]==`ADDC)
					||(id_ir[15:11]==`SUB)||(id_ir[15:11]==`SUBC)
					||(id_ir[15:11]==`CMP)||(id_ir[15:11]==`AND)
					||(id_ir[15:11]==`OR)||(id_ir[15:11]==`XOR))
				begin
					if((id_ir[2:0]==ex_ir[10:8])
					 &&((ex_ir[15:11]!=`NOP)&&(ex_ir[15:11]!=`HALT)
					  &&(ex_ir[15:11]!=`LOAD)&&(ex_ir[15:11]!=`CMP)
					  &&(ex_ir[15:11]!=`JUMP)))
						begin		reg_B <= ALUo;		end
					else if((id_ir[2:0]==mem_ir[10:8])
							&&((mem_ir[15:11]!=`NOP)&&(mem_ir[15:11]!=`HALT)
							&&(mem_ir[15:11]!=`CMP)&&(mem_ir[15:11]!=`JUMP)))
						begin
							if(mem_ir[15:11]==`LOAD)	reg_B <= d_datain;
							else								reg_B <= reg_C;
						end
					else if((id_ir[2:0]==wb_ir[10:8])
							&&((wb_ir[15:11]!=`NOP)&&(wb_ir[15:11]!=`HALT)
							&&(wb_ir[15:11]!=`CMP)&&(wb_ir[15:11]!=`JUMP)))
						begin		reg_B <= reg_C1;		end
					else
						begin		reg_B <= gr[id_ir[2:0]];		end	//r3
				end
			else if(((mem_ir[15:11]==`BZ)&&(zf==1'b1))
					 ||((mem_ir[15:11]==`BNZ)&&(zf==1'b0))
					 ||((mem_ir[15:11]==`BN)&&(nf==1'b1))
					 ||((mem_ir[15:11]==`BNN)&&(nf==1'b0))
					 ||((mem_ir[15:11]==`BC)&&(cf==1'b1))
					 ||((mem_ir[15:11]==`BNC)&&(nf==1'b0))
					 || (mem_ir[15:11]==`JMPR))
				begin		reg_B <= 16'b0;		end	
			else
			begin
			/***********************************************/
				if((id_ir[15:11] == `LOAD)
				 ||(id_ir[15:11] == `SLL)
				 ||(id_ir[15:11] == `SLA)
				 ||(id_ir[15:11] == `SRL)
				 ||(id_ir[15:11] == `SRA))
					reg_B <= {12'b0000_0000_0000, id_ir[3:0]};
				else if((id_ir[15:11] == `BZ)
						||(id_ir[15:11] == `BN)
						||(id_ir[15:11] == `JUMP)
						||(id_ir[15:11] == `JMPR)
						||(id_ir[15:11] == `BC)
						||(id_ir[15:11] == `BNZ)
						||(id_ir[15:11] == `BNN)
						||(id_ir[15:11] == `BNC)
						||(id_ir[15:11] == `ADDI)
						||(id_ir[15:11] == `SUBI))
					reg_B <= {8'b0000_0000, id_ir[7:0]};
				else if((id_ir[15:11] == `STORE))
				begin
					reg_B <= {12'b0000_0000_0000, id_ir[3:0]};
					//smdr <= gr[(id_ir[10:8])];	//for not Hazard
				end
				else if(id_ir[15:11] == `LDIH)
					reg_B <= {id_ir[7:0], 8'b0000_0000};
				else
					reg_B <= gr[id_ir[2:0]];
			end
			
			//smdr
			/********************Hazard**********************/
			if(id_ir[15:11]==`STORE)
				begin
					if((id_ir[10:8]==ex_ir[10:8])
					 &&((ex_ir[15:11]!=`NOP)&&(ex_ir[15:11]!=`HALT)
					 &&(ex_ir[15:11]!=`LOAD)&&(ex_ir[15:11]!=`CMP)
					 &&(ex_ir[15:11]!=`JUMP)))
						begin		smdr <= ALUo;		end
					else if((id_ir[10:8]==mem_ir[10:8])
						   &&((mem_ir[15:11]!=`NOP)&&(mem_ir[15:11]!=`HALT)
							&&(mem_ir[15:11]!=`CMP)&&(mem_ir[15:11]!=`JUMP)))
						begin
							if(mem_ir[15:11]==`LOAD)	smdr <= d_datain;
							else								smdr <= reg_C;
						end
					else if((id_ir[10:8]==wb_ir[10:8])
							&&((wb_ir[15:11]!=`NOP)&&(wb_ir[15:11]!=`HALT)
							&&(wb_ir[15:11]!=`CMP)&&(wb_ir[15:11]!=`JUMP)))
						begin		smdr <= reg_C1;		end
					else
						begin		smdr <= gr[id_ir[10:8]];		end
				end
			else
				smdr <= gr[id_ir[10:8]];
			
			/********************Hazard**********************/
		end
		else
		begin
			ex_ir <= ex_ir;
			reg_A <= reg_A;
			reg_B <= reg_B;
			smdr <= smdr;
		end
	end
	/***************************************/
	
	/****************EX*********************/
	always@(posedge clock or posedge reset)
	begin
		if(reset)
		begin
			mem_ir <= 16'b0000_0000_0000_0000;
			reg_C <= 16'b0000_0000_0000_0000;
			smdr1 <= 16'b0000_0000_0000_0000;
			zf <= 1'b0;
			nf <= 1'b0;
			cf <= 1'b0;
			dw <= 1'b0;
		end
		else if(state == `exec)
		begin
			mem_ir <= ex_ir;
			reg_C <= ALUo;
			smdr1 <= smdr;
			if((ex_ir[15:11] == `ADD)
			 ||(ex_ir[15:11] == `CMP)
			 ||(ex_ir[15:11] == `ADDI)
			 ||(ex_ir[15:11] == `SUB)
			 ||(ex_ir[15:11] == `SUBI)
			 ||(ex_ir[15:11] == `LDIH)
			 ||(ex_ir[15:11] == `SLL)
			 ||(ex_ir[15:11] == `SRL)
			 ||(ex_ir[15:11] == `SLA)
			 ||(ex_ir[15:11] == `SRA)
			 ||(ex_ir[15:11] == `ADDC)
			 ||(ex_ir[15:11] == `SUBC)
			 ||(ex_ir[15:11] == `AND)
			 ||(ex_ir[15:11] == `OR)
			 ||(ex_ir[15:11] == `XOR))
			begin
				if(ALUo == 16'b0000_0000_0000_0000)
					zf <= 1'b1;
				else
					zf <= 1'b0;
				
				if(ALUo[15] == 1'b1)
					nf <= 1'b1;
				else
					nf <= 1'b0;
			end
			else
			begin
				zf <= zf;
				nf <= nf;
			end
			
			if(ex_ir[15:11] == `STORE)
			begin
				dw <= 1'b1;
			end
			else
			begin
				dw <= 1'b0;
			end
		end
		else
		begin
			reg_C <= reg_C;
			smdr1 <= smdr1;
			dw <= dw;
		end
	end
	//ALU
	reg cf_temp;
	always@(reg_A or reg_B or ex_ir[15:11])
	begin
		if(state == `exec)
		begin
			if(reset)
			begin
				ALUo <= 16'b0000_0000_0000_0000;
				cf_temp <= 0;
			end
			else
				case(ex_ir[15:11])
					`NOP:		{cf_temp, ALUo} <= {cf_temp, ALUo};
					`HALT:	{cf_temp, ALUo} <= {cf_temp, ALUo};
					`AND:		{cf_temp, ALUo} <= {cf_temp, reg_A & reg_B};
					`OR:		{cf_temp, ALUo} <= {cf_temp, reg_A | reg_B};
					`XOR:		{cf_temp, ALUo} <= {cf_temp, reg_A ^ reg_B};
					`SLL:		{cf_temp, ALUo} <= {cf_temp, reg_A << reg_B};
					`SRL:		{cf_temp, ALUo} <= {cf_temp, reg_A >> reg_B};
					`SLA:		{cf_temp, ALUo} <= {cf_temp, $signed(reg_A) <<< reg_B};
					`SRA:		{cf_temp, ALUo} <= {cf_temp, $signed(reg_A) >>> reg_B};
					`JUMP:	{cf_temp, ALUo} <= {cf_temp, reg_B};
					`LDIH:	{cf_temp, ALUo} <= {1'b0 + reg_A} + {1'b0 + reg_B};
					`ADD:		{cf_temp, ALUo} <= {1'b0 + reg_A} + {1'b0 + reg_B};
					`ADDI:	{cf_temp, ALUo} <= {1'b0 + reg_A} + {1'b0 + reg_B};
					`ADDC:	{cf_temp, ALUo} <= {1'b0 + reg_A} + {1'b0 + reg_B} + cf;
					`SUB:		{cf_temp, ALUo} <= {1'b0 + reg_A} - {1'b0 + reg_B};
					`SUBI:	{cf_temp, ALUo} <= {1'b0 + reg_A} - {1'b0 + reg_B};
					`SUBC:	{cf_temp, ALUo} <= {1'b0 + reg_A} - {1'b0 + reg_B} - cf;
					`CMP:		{cf_temp, ALUo} <= {1'b0 + reg_A} - {1'b0 + reg_B};
					`LOAD:	begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`STORE:	begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`JMPR:	begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BZ:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BNZ:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BN:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BNN:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BC:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					`BNC:		begin ALUo <= reg_A + reg_B; cf_temp <= cf_temp; end
					default:	{cf_temp, ALUo} <= {cf_temp, ALUo};
				endcase
		end
	end
	/***************************************/
	
	/***************MEM*********************/
	always@(posedge clock or posedge reset)
	begin
		if(reset)
		begin
			reg_C1 <= 16'b0000_0000_0000_0000;
			wb_ir <= 16'b0000_0000_0000_0000;
		end
		else if(state == `exec)
		begin
			wb_ir <= mem_ir;
			cf <= cf_temp;
			if(mem_ir[15:11] == `LOAD)
				reg_C1 <= d_datain;
			else
				reg_C1 <= reg_C;
		end
	end
	/***************************************/
	
	/****************WB********************/
	always@(posedge clock or posedge reset)
	begin
		if(reset)
		begin
			gr[0] <= 16'b0000_0000_0000_0000;
			gr[1] <= 16'b0000_0000_0000_0000;
			gr[2] <= 16'b0000_0000_0000_0000;
			gr[3] <= 16'b0000_0000_0000_0000;
			gr[4] <= 16'b0000_0000_0000_0000;
			gr[5] <= 16'b0000_0000_0000_0000;
			gr[6] <= 16'b0000_0000_0000_0000;
			gr[7] <= 16'b0000_0000_0000_0000;
		end
		else if(state == `exec)
		begin
			if((wb_ir[15:11] == `LOAD)
			 ||(wb_ir[15:11] == `ADD)
			 ||(wb_ir[15:11] == `ADDI)
			 ||(wb_ir[15:11] == `ADDC)
			 ||(wb_ir[15:11] == `SUB)
			 ||(wb_ir[15:11] == `SUBI)
			 ||(wb_ir[15:11] == `SUBC)
			 ||(wb_ir[15:11] == `AND)
			 ||(wb_ir[15:11] == `OR)
			 ||(wb_ir[15:11] == `XOR)
			 ||(wb_ir[15:11] == `SLL)
			 ||(wb_ir[15:11] == `SRL)
			 ||(wb_ir[15:11] == `SLA)
			 ||(wb_ir[15:11] == `SRA)
			 ||(wb_ir[15:11] == `LDIH))
				gr[wb_ir[10:8]] <= reg_C1;
		end
		else
		begin
				gr[wb_ir[10:8]] <= gr[wb_ir[10:8]];
		end
	end
	/***************************************/
	
	/**************select Y*****************/
	always@(*)
	begin
		case(select_y)
			4'b0000:	y <= reg_C;
			4'b0001:	y <= reg_A;
			4'b0010:	y <= reg_B;
			4'b0011:	y <= {pc, 8'b0000_0000};
			4'b0100:	y <= id_ir;
			4'b0101:	y <= smdr;
			4'b0110:	y <= reg_C1;
			4'b0111:	y <= smdr1;
			4'b1000:	y <= ex_ir;
			4'b1001:	y <= mem_ir;
			4'b1010:	y <= wb_ir;
			default: y <= reg_C;
		endcase
	end
	/***************************************/
endmodule

PCPUcontroller.v

`timescale 1ns / 1ps

module PCPUcontroller(
	input myclk,
	input button,
	input reset,
	output reg sense
    );

	parameter STOP = 2'b00, INC = 2'b01, TRAP = 2'b10;
	
	reg [1:0] state, nextstate;
	
	always@(posedge myclk or posedge reset)
	begin
		if(reset)
			state <= STOP;
		else
			state <= nextstate;
	end
	
	always@(*)
	begin
		case(state)
			STOP:
				if(button)	nextstate <= INC;
				else			nextstate <= STOP;
			INC:				nextstate <= TRAP;
			TRAP:
				if(button)	nextstate <= TRAP;
				else			nextstate <= STOP;
			default:			nextstate <= STOP;
		endcase
	end
	
	always@(*)
	begin
		if(reset)
			sense <= 0;
		else
			case(state)
				INC:		sense <= 1'b1;
				default:	sense <= 1'b0;
			endcase
	end

endmodule

VTF_CPU.v

`timescale 1ns / 1ps

module VTF_CPU;

	// Inputs
	reg clk;
	reg enable;
	reg reset;
	reg [3:0] SW;
	reg start;
	reg button;

	// Outputs
	wire [6:0] light;
	wire [3:0] en;

	// Instantiate the Unit Under Test (UUT)
	CPU uut (
		.clk(clk), 
		.enable(enable), 
		.reset(reset), 
		.SW(SW), 
		.start(start), 
		.button(button), 
		.light(light), 
		.en(en)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		enable = 0;
		reset = 0;
		SW = 0;
		start = 0;
		button = 0;

		// Wait 100 ns for global reset to finish
		#100;
		
		// Test by me
		/*$display("pc :     id_ir      :reg_A:reg_B:reg_C:da:dd  :w:reC1:gr1 :gr2 : gr3: dm0: dm1: dm2");
		$monitor("%d:%b:%h :%h :%h :%h:%h:%b:%h:%h:%h:%h:%h:%h:%h", 
			uut.pcpu.pc, uut.pcpu.id_ir, uut.pcpu.reg_A, uut.pcpu.reg_B, uut.pcpu.reg_C,
			uut.d_addr, uut.d_dataout, uut.d_we, uut.pcpu.reg_C1, uut.pcpu.gr[1], uut.pcpu.gr[2], uut.pcpu.gr[3],
			uut.d_mem.d_mem[0], uut.d_mem.d_mem[1], uut.d_mem.d_mem[2]);*/
		// Bubble Test
		$display("pc :     id_ir      :reg_A:reg_B:reg_C:da:dd  :w:reC1:gr1 :gr2 : gr3: dm0: dm1: dm2: dm3: dm4: dm5: dm6: dm7: dm8: dm9: dm10");
		$monitor("%d:%b:%h :%h :%h :%h:%h:%b:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h:%h", 
			uut.pcpu.pc, uut.pcpu.id_ir, uut.pcpu.reg_A, uut.pcpu.reg_B, uut.pcpu.reg_C,
			uut.d_addr, uut.d_dataout, uut.d_we, uut.pcpu.reg_C1, uut.pcpu.gr[1], uut.pcpu.gr[2], uut.pcpu.gr[3],
			uut.d_mem.d_mem[0], uut.d_mem.d_mem[1], uut.d_mem.d_mem[2], uut.d_mem.d_mem[3], uut.d_mem.d_mem[4], uut.d_mem.d_mem[5],
			uut.d_mem.d_mem[6], uut.d_mem.d_mem[7], uut.d_mem.d_mem[8], uut.d_mem.d_mem[9], uut.d_mem.d_mem[10]);
			
      enable <= 0; start <= 0;
		// Add stimulus here
		#10 reset <= 1;
		#10 reset <= 0;
		#10 enable <= 1;
		#10 start <=1;
		//#10 start <= 0;
		//Test Need 100.00us
		#100000 $display("After Computing");
					$display("dm0 = %h", uut.d_mem.d_mem[0]);
					$display("dm1 = %h", uut.d_mem.d_mem[1]);
					$display("dm2 = %h", uut.d_mem.d_mem[2]);
					$display("dm3 = %h", uut.d_mem.d_mem[3]);
					$display("dm4 = %h", uut.d_mem.d_mem[4]);
					$display("dm5 = %h", uut.d_mem.d_mem[5]);
					$display("dm6 = %h", uut.d_mem.d_mem[6]);
					$display("dm7 = %h", uut.d_mem.d_mem[7]);
					$display("dm8 = %h", uut.d_mem.d_mem[8]);
					$display("dm9 = %h", uut.d_mem.d_mem[9]);
					$display("dm10 = %h", uut.d_mem.d_mem[10]);
					$display("dm11 = %h", uut.d_mem.d_mem[11]);
	
	end
   always #20 button = ~button;
	always #5 clk = ~clk;
endmodule

調試小tips:
工程文件中有一份PCPU_OnebyOne.wcfg的文件,仿真絲打開即可比較舒服得觀察調試,打開后需要重新跑一下仿真

傳送門:

  • CPU2
  • CPU2_Add
  • CPU2_Bubble
  • CPU2_GCD_LCM
  • CPU2_Mytest
  • CPU2_Sort

點擊這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM