<2007年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          常用鏈接

          留言簿(2)

          隨筆檔案(9)

          文章分類(5)

          文章檔案(5)

          收藏夾(4)

          eBOOK

          JAVA

          MyLife

          Study

          搜索

          •  

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜


          計算機組成實驗報告

          指導教師姓名:戴老師

          學生姓名:wyz_wx@163.com

          實驗日期:星期六上午

          目錄

          第一部分 運用TDM-CM++實驗臺的實驗

          實驗三:微控制器實驗

          第二部分 Verilog-HDL進行計算機設計的實驗

          實驗一:帶進位的四位加法器

          實驗二:時鐘發生器

          實驗三:指令寄存器

          實驗五:數據控制器

          實驗九:狀態控制器

          附一CPU設計

          附二:實驗波形圖

          第一部分 運用TDM-CM++實驗臺的實驗

          實驗三:微控制器實驗

          (與《實驗五:基本微型機設計與實現》一起分析)

          [實驗目的]

          1 掌握時序產生器的組成原理。
          2 掌握微程序控制器的組成原理。
          3 掌握微程序的編制,寫入,觀察微程序的運行。

          [實驗設備]

          TDN-CM++計算機組成原理教學實驗系統一臺。

          [實驗原理]

          1. 時序控制電路

          時序控制電路采用一片CPLD芯片,電路框圖如圖。產生4個等間隔的時序信號TS1TS4

          φ:時鐘脈沖輸入端,接到方波發生器的輸出(H23)。WI調頻率,W2調脈寬。
          START鍵是實驗板上一個微動開關START的按鍵信號。
          STEP(單步開關):STEP開關為0時(EXEC),一旦按下啟動鍵,時序信號TS1TS4將周而復始地發送出去。
          STOP:撥動開關。STOP停機;RUN運行。
          CLR:撥動開關。時序清零。
          TS1~TS4等間隔的時序信號輸出。
          2 微指令格式

          微指令字長共24位,其中UA5UA06位的后續微地址,ABC為三個譯碼字段,分別由三個控制位譯碼出多位。

          24

          23

          22

          21

          20

          19

          18

          17

          16

          15 14 13

          12 11 10

          9 8 7

          6

          5

          4

          3

          2

          1

          S3

          S2

          S1

          S0

          M

          Cn

          WE

          A9

          A8

          A

          B

          C

          μA5

          μA4

          μA3

          μA2

          μA1

          μA0

          3 微程序控制電路

          微程序控制電路組成:控制存儲器、微命令寄存器、微地址寄存器。

          編程開關 : PROM(編程):根據微地址和微指令格式將微指令二進制代碼寫入到控制存儲器中;READ(校驗):可以對寫入控制存儲器中的二進制代碼進行驗證;RUN(運行):只要給出微程序的入口微地址,則可根據微程序流程圖自動執行微程序。

          [實驗步驟以及結果]

          1 連接實驗線路,接通電源。
          2 運行實驗臺系統程序NCMP53,按F7
          3 把時序電路中“STOP”開關置“RUN”、“STEP”開關置“EXEC”,按START,用PC模擬字波器觀察φ,TS1~TS4波形,畫出波形圖,測出周期和脈沖寬度。
          4 聯機裝載微程序(把編程開關撥到PROM狀態)(按F4,輸入文件名EXI.TXT)檢查微程序是否正確(按F3,輸入起始地址,對照37頁微程序代碼。)運行實驗臺系統程序NCMP53,按F7
          5 SWITCH單元μMA5~μAO接線接到微控制器單元的SE6~SE1MA5~MA0全置“1”。單步運行微程序。通過改變開關狀態,把所有微程序全部執行。(注意:微地址“1”要變“0”)

          [解釋數據通路]

          結合實驗五,對照微程序流程圖和基本微型機的硬件組成解釋數據通路:

          SWA

          SWB

          控制臺命令

          0

          0

          讀內存

          0

          1

          寫內存

          1

          1

          啟動程序

          默認SWA=1SWB=1,處于啟動程序狀態。經過控制臺指令地址從00-》01,啟動控制臺。

          第二部分 用Verilog-HDL進行計算機設計的實驗

          [實驗目的]

          1 了解工作原理。
          2 學會編寫模塊程序
          3 學會編寫測試的模塊程序。

          [實驗設備]

          1 常用微機一臺;
          2 Model Sim SEPLUS5.6 軟件一套。

          [實驗步驟]

          1 編寫模塊程序;
          2 編寫測試程序;
          3 編輯編譯這兩個模塊程序;
          4 運行模擬、觀察波形、驗證設計的正確性。

          [實驗內容]

          實驗一 帶進位四位加法器

          實驗二 時鐘發生器

          實驗五 數據控制器

          實驗九 狀態控制器

          附:實驗十:CPU

          實驗一:帶進位的四位加法器

          [實驗原理]

          4位輸入信號:add_a[4],add_b[4]

          輸入進位:carry

          時鐘信號:clk

          4位輸出信號:sum[4]

          進位信號:flow

          [實驗步驟以及結果]

          1. 模塊程序add4.v

          module add4(add_a,add_b,sum,flow,clk,carry);

          output [3:0] sum; //聲明輸出信號sum

          output flow; //聲明輸出高位進位float

          input [3:0] add_a,add_b; //聲明兩個4位二進制的輸入信號add_aadd_b

          input carry; //聲明輸入信號低位進位信號carry

          input clk; //聲明時鐘信號CLK

          reg [3:0] sum; //定義了一個4位的名為SUM的寄存器

          reg flow; //定義了一個1位的名為FLOW的寄存器

          always@(negedge clk) //CLK下降沿時,執行下列語句

          begin

          sum<=add_a+add_b+carry;//sum<=add_a+add_b+carry;

          end

          always@(posedge clk) //CLK上升沿時,執行下列語句

          begin

          flow<=(add_a[3]&add_b[3])|((add_a[3]|add_b[3])&sum[3]<1);

          end //計算FLOW的數值

          endmodule

          2.測試程序add4_test.tst

          module add4_test;

          reg [3:0] add_a,add_b;

          reg carry;

          reg clk;

          wire [3:0] sum;

          wire flow;

          add4 add4(add_a,add_b,sum,flow,clk,carry);

          initial begin

          carry=0;

          clk=1;

          add_a=4'b1011;

          add_b=4'b0101;

          end

          always #1 clk=~clk; //產生時鐘信號

          always #5 carry=~carry; //間隔5,低位進位信號改變數值

          always@(posedge clk)

          begin

          add_a<=add_b+1;

          add_b<=add_a+1; //改變add_aadd_b

          end

          endmodule

          3.仿真波形,見附件圖;

          實驗二:時鐘發生器

          [實驗原理]

          時鐘發生器clkgen利用外來時鐘信號材料clk1,fetch,aluclk,送往CPU的其他部見。其中fetch是外部時鐘,利用fetch的上升沿來觸發CPU控制器開始執行一條指令,同時fetch信號還將控制地址多路器輸出指令地址和數據地址;clk1信號用作指令寄存器、累加器、狀態控制器的時鐘信號;alu_clk則用于觸發算術邏輯運算單元。

          時鐘信號:clk

          中間信號:clk2=~clk2(clk1↑);clk4=~clk4(clk2↓)

          輸出信號:clk1=~clk;

          fetch=~fetch(clk4↑);

          alu_clk=clk2&clk4&!fetch

          [實驗步驟以及結果]

          1. 模塊程序clkgen.v

          module clkgen(clk,clk1,fetch,alu_clk);

          output clk1,fetch,alu_clk; //聲明輸出變量clk1,fetch,alu_clk

          input clk; //聲明時鐘信號clk

          reg clk2,clk4,fetch; //定義31位寄存器名為clk2,clk4,fetch

          initial //初始化

          begin

          clk2=0;

          clk4=1;

          fetch=0;

          end

          assign clk1=~clk; //邏輯功能定義

          assign alu_clk=clk2&clk4&!fetch;

          always@(posedge clk1) //每當clk1的信號出現上升沿時,下列語句被不斷重復執行

          begin

          clk2<=~clk2;

          end

          always@(negedge clk2)

          begin

          clk4<=~clk4;

          end

          always@(posedge clk4)

          begin

          fetch<=~fetch;

          end

          endmodule

          2. 測試程序clkgen_test.v

          module clkgen_test;

          reg clk;reg clk2;reg clk4;

          clkgen clkgen(clk,clk1,fetch,alu_clk);

          initial

          begin

          clk=1;

          end

          always #1 clk=~clk; //信號反相,#1表示延遲1個時間單位。

          endmodule

          3.仿真波形,見附錄二。

          實驗六:數據控制器

          [實驗原理]

          數據控制器的作用是控制累加器數據輸出,由于數據總線是各種操作時傳送數據的公共通道,不同的情況下傳送不同的內容。累加器的數據只有在需要往RAM區或端口寫時才允許輸出,否則應呈現高阻態,以允許其他部件使用數據總線。數據控制其何時輸出累加器的數據則由狀態控制器輸出的控制信號DAYA_ENA決定。

          [實驗步驟以及結果]

          1模塊程序datactl.v

          module datactl(data,in,data_ena);

          output[7:0] data;

          input[7:0] in;

          input data_ena; //聲明輸入輸出

          assign data=(data_ena)?in:8'bzzz_zzzz;//data_ena為真,則允許輸出,否則

          //呈現高阻態

          endmodule

          2.測試程序datactl_test.v

          module datactl_test;

          wire [7:0] data;

          reg [7:0] in;

          reg data_ena;

          datactl datactl(data,in,data_ena);

          initial begin

          data_ena=0;

          in<=8'b0101_0101;

          end

          always #1 data_ena=~data_ena; //間隔2nsdata_ena改變

          always #1 in=in+1; //間隔1nsin的值在原來的基礎上增1

          endmodule

          3.仿真波形,見附錄二。

          實驗九:狀態控制器

          [實驗原理]

          狀態控制器有兩部分組成:(1)狀態機;(2)狀態控制器。

          狀態控制器接受復位信號RST,當RST有效時通過信號ENA使其為0,輸入到狀態機中停止狀態機的工作。

          狀態機時CPU的控制核心,用于產生一系列的狀態信號,啟動或停止某些部件。CPU何時進行讀指令讀寫I/O端口,RAM區等操作,都是由狀態機來控制的。狀態機的當前狀態,由變量STATE記錄,STATE的值就是當前這個指令周期中經過的時鐘數。

          指令周期由8個時鐘周期組成,每個時鐘周期都要完成固定的操作。

          第0個時鐘,因為CPU狀態控制器的輸出RD和LOAD_IR為高電平,其余均為低電平。指令寄存器寄存由ROM送來的高8位指令代碼。

          第1個時鐘,與上一時鐘相比只是INC_PC從0變為1,故PC增1,ROM送來低8位指令代碼,指令寄存器寄存該8位代碼。

          第2個時鐘,空操作。

          第3個時鐘,PC增1,指向下一條指令。若操作符為HLT,則輸出信號HLT為高;如果操作符不為HLT,除了PC增1外,其他各控制線輸出為零。

          第4個時鐘,若操作符號為ANDD,ADD,XORR或LDA,讀相應地址的數據;若為JMP,將目的地址送給程序計數器;若為STO,輸出累加器數據。

          第5個時鐘,若操作符為ANDD,ADD,XORR,算術運算器就進行相應的運算;若為LDA,就把數據通過算術運算器送給累加器;若為SKZ,線判斷累加器的值是否為0,如果為,PC增1,否則保持原值;若為JMP,鎖存目的地址;若為STO,將數據寫入地址處。

          第6個時鐘,空操作。

          第7個時鐘,若操作符為SKZ且累加器值為0,則PC值再增加1,跳過一條指令,否則PC無變化。

          [實驗步驟以及結果]

          1模塊程序machinectl.v

          module machinectl(ena,fetch,rst);

          output ena;

          input fetch,rst; //聲明輸入和輸出

          reg ena; //定義ena的寄存器

          always @(posedge fetch or posedge rst)//fetch或者rst信號出現上升沿時,

          begin //根據rst的值確定ena的值

          if(rst)

          ena<=0;

          else

          ena<=1;

          end

          endmodule

          machine.v

          module machine(inc_pc,load_acc,load_pc,rd,wr,load_ir,datactl_ena,

          halt,clk1,zero,ena,opcode);

          output inc_pc,load_acc,load_pc,rd,wr,load_ir;

          output datactl_ena,halt;

          input clk1,zero,ena;

          input [2:0] opcode;

          reg inc_pc,load_acc,load_pc,rd,wr,load_ir;

          reg datactl_ena,halt;

          reg [2:0] state; //聲明輸入輸出,以及定義寄存器

          parameter //parameter來定義標識符形式的常量

          HLT=3'b000,

          SKZ=3'b001,

          ADD=3'b010,

          ANDD=3'b011,

          XORR=3'b100,

          LDA=3'b101,

          STO=3'b110,

          JMP=3'b111;

          always @(negedge clk1)

          begin

          if(!ena) //如果接收到復位信號RST,進行復位操作

          begin

          state<=3'b000;

          {inc_pc,load_acc,load_pc,rd}<=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          ctl_cycle; //執行任務ctl_cycle

          end

          //------------task ctl_cycle------------任務開始---------

          task ctl_cycle;

          begin

          casex(state) //case語句

          0: //rdload_ir均為高電平,其余為低電平。指令寄存器寄

          Begin //存由ROM送來的高8位指令代碼

          {inc_pc,load_acc,load_pc,rd}<=4'b0001;

          {wr,load_ir,datactl_ena,halt}<=4'b0100;

          state<=1;

          end

          1: //INC_PC0變為1,故PC1ROM送來低8位指令代碼,

          Begin //指令寄存器寄存該8位代碼

          {inc_pc,load_acc,load_pc,rd}<=4'b1001;

          {wr,load_ir,datactl_ena,halt}<=4'b0100;

          state<=2;

          end

          2: //空操作

          Begin

          {inc_pc,load_acc,load_pc,rd}<=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          state<=3;

          end

          3: //PC1,指向下一條指令

          begin

          if(opcode==HLT) //若操作符為HLT,則輸出信號HLT為高

          begin

          {inc_pc,load_acc,load_pc,rd}<=4'b1000;

          {wr,load_ir,datactl_ena,halt}<=4'b0001;

          end

          else //否則其他各控制線輸出為零。

          begin

          {inc_pc,load_acc,load_pc,rd}<=4'b1000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          state<=4;

          end

          4:

          begin

          if(opcode==JMP) //若為JMP,將目的地址送給程序計數器

          begin

          {inc_pc,load_acc,load_pc,rd}<=4'b0010;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)

          begin //若操作符號為ANDD,ADD,XORRLDA,讀相應地址的數據

          {inc_pc,load_acc,load_pc,rd}<=4'b0001;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          if(opcode==STO) //若為STO,輸出累加器數據

          begin {inc_pc,load_acc,load_pc,rd}<=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0010;

          end

          else

          begin //其他則為空操作

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          state<=5;

          end

          5:

          begin

          if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)

          begin //若操作符為ANDD,ADD,XORR,算術運算器就進行相應的運算

          {inc_pc,load_acc,load_pc,rd} <=4'b0101;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          if (opcode==SKZ&&zero==1) //若為SKZ,線判斷累加器的值是否為0,如果為,

          begin // PC1,否則保持原值

          {inc_pc,load_acc,load_pc,rd} <=4'b1000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          if(opcode==JMP) //若為JMP,鎖存目的地址

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b1010;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          if(opcode==STO) //若為STO,將數據寫入地址處

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b1010;

          end

          else

          begin //其他則為空操作

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          state<=6;

          end

          6:

          begin

          if(opcode==STO) //若為STO,將數據寫入地址處

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0010;

          end

          else

          if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)

          begin //若操作符號為ANDD,ADD,XORRLDA,讀相應地址的數據

          {inc_pc,load_acc,load_pc,rd} <=4'b0001;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else //其余為空操作

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          state<=7;

          end

          7:

          begin

          if(opcode==SKZ&&zero==1) //若操作符為SKZ且累加器值為0

          begin //PC值再增加1,跳過一條指令,否則PC無變化

          {inc_pc,load_acc,load_pc,rd} <=4'b1000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          else

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          end

          state<=0;

          end

          default: //缺省為空操作

          begin

          {inc_pc,load_acc,load_pc,rd} <=4'b0000;

          {wr,load_ir,datactl_ena,halt}<=4'b0000;

          state<=0;

          end

          endcase

          end

          endtask

          //-------------end of task ctl_cycle-----任務結束-----------------

          endmodule

          control.v

          module control(clk1, zero, fetch, rst, opcode, inc_pc, load_acc, load_pc, rd, wr, load_ir, halt, datactl_ena);

          output inc_pc,load_acc,load_pc,rd,wr,load_ir;

          output datactl_ena,halt;

          input clk1,zero,fetch,rst;

          input [2:0] opcode; //聲明輸入和輸出

          wire ena; //定義wire類型的ena

          machinectl machinectl(.fetch(fetch),.rst(rst),.ena(ena));

          machine machine(.clk1(clk1),.zero(zero),.opcode(opcode), .ena(ena),.inc_pc(inc_pc),.load_acc(load_acc),.load_pc(load_pc),

          .rd(rd),.wr(wr),.load_ir(load_ir),.halt(halt),.datactl_ena(datactl_ena)); //machinectlmachine連接起來

          //machinectl.vmachine.v均為上層文件

          endmodule

          2.測試程序control_test.tst

          module control_test;

          wire inc_pc ,load_acc ,load_pc, rd, wr ,load_ir ,datactl_ena, halt;

          wire clk1,fetch,alu_clock;

          reg zero, rst;

          reg [2:0] opcode;

          reg clk;

          clkgen clkgen(clk,clk1,fetch,alu_clk);

          //用一個CLKGEN部件來產生clk1,fetch序列

          control control(clk1, zero, fetch, rst, opcode, inc_pc, load_acc, load_pc, rd, wr, load_ir, halt, datactl_ena);

          initial begin

          rst=0;

          clk=1;

          zero=0;

          opcode=3'b000;

          end

          always #1 clk=~clk; //產生時鐘信號,1個時鐘周期為2nm

          always #160 zero=~zero;

          always #16 opcode<=opcode+1;//經過8個時鐘信號周期,opcode改變一次

          endmodule

          3.仿真波形,見附錄二;

          附錄一:

          實驗十:CPU

          源代碼

          包含:

          accum.v累加器

          adr.v地址多路器

          alu.v算術運算器

          clkgen.v 時鐘發生器

          control.v 狀態控制器

          machine.v

          machinectl.v

          counter.v程序計數器

          datactl.v數據控制器

          register.v指令寄存器

          sig.v //生成信號CLK

          addr_decode.v

          ram.v

          rom.v //外部器件

          cpu.v //CPU集成

          risc.v //CPU+外部器件

          rscsys_ex1.v //測試仿真文件

          test1.dat

          test1.pro

          test2.dat

          test2.pro

          test3.dat

          test3.pro

          cpu.v

          module cpu(rst,clk,rd,wr,halt,addr,data);

          input rst;

          input clk;

          output rd;

          output wr;

          output halt;

          output [12:0] addr;

          output [7:0] data;

          wire clk1 fetch alu_clk;

          wire [15:0] opc_iraddr;

          wire [7:0] accum_data;

          wire [7:0] alu_out;

          wire zeroinc_pc load_acc load_pcload_ir datactl_ena;

          wire [12:0] pc_addr;

          wire [7:0] data_altera;

          register register26p(.opc_iraddr(opc_iraddr), .data(data_altera), .ena(load_ir), .clk1(clk1), .rst(rst));

          clkgen clkgen27p(.clk(clk), .clk1(clk1), .fetch(fetch), .alu_clk(alu_clk));

          accum accum1p(.accum(accum_data), .data(alu_out), .ena(load_acc), .clk1(clk1), .rst(rst));

          datactl datactl24p(.data(data_altera), .in(alu_out),.data_ena(datactl_ena));

          adr adr22p(.addr(addr), .fetch(fetch), .ir_addr(opc_iraddr[12:0]), .pc_addr(pc_addr));

          counter counter11p( .pc_addr(pc_addr), .ir_addr(opc_iraddr[12:0]), .load(load_pc), .clock(inc_pc), .rst(rst));

          alu alu15p(.alu_out(alu_out), .zero(zero), .data(data_altera), .accum(accum_data), .alu_clk(alu_clk), .opcode(opc_iraddr[15:13]));

          control control12p(.clk1(clk1), .zero(zero), .fetch(fetch), .rst(rst), .opcode(opc_iraddr[15:13]),.inc_pc(inc_pc), .load_acc(load_acc), .load_pc(load_pc), .rd(rd), .wr(wr), .load_ir(load_ir), .halt(halt), .datactl_ena(datactl_ena));

          assign data = data_altera;

          endmodule

          sig.v

          module sig(clk);

          output clk;

          reg clock;

          initial

          begin

          clock=0;

          end

          assign clk=clock;

          always #1 clock=~clock;

          endmodule

          Risc.v

          module risc(rst);

          reg rst;

          wire clk, read, write, halt;

          wire [7:0] data;

          wire [12:0] addr;

          wire ramsel, romsel;

          sig sys_sig5p(.clk(clk));

          cpu sys_rsc4p(.rst(rst),.clk(clk),.rd(read),.wr(write),.halt(halt),.addr(addr[12:0]),.data(data[7:0]));

          ram sys_ram3p(.data(data[7:0]),.addr(addr[9:0]), .ena(ramsel), .read(read), .write(write));

          rom sys_rom1p(.addr(addr[12:0]),.ena(romsel), .read(read), .data(data[7:0]));

          addr_decode sys_addr_decode2p(.addr(addr[12:0]), .romsel(romsel), .ramsel(ramsel));

          endmodule

          recsya_ex1.v

          //------------------------rscsys_ex1.v-------------------------------

          `define VLP vlog1

          `define PERIOD 100 //matches clkgen/vlog_behaviorial/verilog.v

          module rscsys_ex1;

          reg reset_req;

          integer test;

          reg [(3*8):0] mnemonic; //array that holds 3 8-bit ASCII characters

          reg [12:0] PC_addr,IR_addr;

          assign `VLP.rst =reset_req;

          risc vlog1(rst);

          initial //display time in nanoseconds

          begin

          $timeformat(-9,1,"ns",12);

          display_debug_message;

          end

          always @(posedge `VLP.halt) // STOP when HALT instruction decoded

          begin

          #500

          $display("\n************************************");

          $display("*A HALT INSTRUCTION WAS PROCESSED!!! *");

          $display("************************************\n");

          display_debug_message;

          end

          task display_debug_message;

          begin

          $display("\n************************************");

          $display("*THE FOLLOWING DEBUG TASK ARE AVAILABLE: *");

          $display("* test1 to load the 1st diagnostic program. *");

          $display("* test2 to load the 2nd diagnostic program. *");

          $display("* test3 to load the Fibonacci program.*");

          $display("************************************\n");

          test1;

          test2;

          test3;

          $stop;

          end

          endtask

          task test1;

          begin

          test = 0;

          disable MONITOR;

          $readmemb("test1.pro",`VLP.sys_rom1p.memory);

          $display("rom loaded successfully!");

          $readmemb("test1.dat",`VLP.sys_ram3p.ram);

          $display("ram loaded successfully!");

          #1 test = 1;

          sys_reset;

          end

          endtask

          task test2;

          begin

          test = 0;

          disable MONITOR;

          $readmemb("test2.pro",`VLP.sys_rom1p.memory);

          $display("rom loaded successfully!");

          $readmemb("test2.dat",`VLP.sys_ram3p.ram);

          $display("ram loaded successfully!");

          #1 test = 2;

          sys_reset;

          end

          endtask

          task test3;

          begin

          test = 0;

          disable MONITOR;

          $readmemb("test3.pro",`VLP.sys_rom1p.memory);

          $display("rom loaded successfully!");

          $readmemb("test3.dat",`VLP.sys_ram3p.ram);

          $display("ram loaded successfully!");

          #1 test = 3;

          sys_reset;

          end

          endtask

          task sys_reset;

          begin

          reset_req = 0;

          #(`PERIOD * 0.7) reset_req = 1;

          #(1.5 * `PERIOD) reset_req = 0;

          end

          endtask

          always @(test)

          begin: MONITOR

          case (test)

          1: begin // display results when running test 1

          $display("\n*** RUNNING CPUtest1 ----The Basic CPU Diagnostic Program ***");

          $display("\n TIME PC INSTR ADDR DATA");$display("-------");

          while(test==1)

          @(`VLP.sys_rsc4p.adr22p.pc_addr)

          if((`VLP.sys_rsc4p.adr22p.pc_addr%2==1)&&(`VLP.sys_rsc4p.adr22p.fetch==1))

          begin

          #60 PC_addr<=`VLP.sys_rsc4p.adr22p.pc_addr-1;

          IR_addr<=`VLP.sys_rsc4p.adr22p.ir_addr;

          #340 $strobe("%t %h %s %h %h",

          $time,PC_addr,mnemonic,IR_addr,`VLP.data);

          end

          end

          2:begin

          $display("\n***RUNNING CPUtest2-The ad cpu program***");

          $display("\n time pc instr addr data");

          $display("-------------------------");

          while(test==2)

          @(`VLP.sys_rsc4p.adr22p.pc_addr)

          if((`VLP.sys_rsc4p.adr22p.pc_addr%2==1)&&(`VLP.sys_rsc4p.adr22p.fetch==1))

          begin

          #60 PC_addr<=`VLP.sys_rsc4p.adr22p.pc_addr-1;

          IR_addr<=`VLP.sys_rsc4p.adr22p.ir_addr;

          #340 $strobe("%t %h %s %h %h",

          $time,PC_addr,mnemonic,IR_addr,`VLP.data);

          end

          end

          3:begin

          $display("\n***RUNNING CPUtest3- an executable program***");

          $display("***this pro should calculate the fibaci");

          $display("***no sequence from 0 to 144***");

          $display("\nTIME FIBOCI NO");

          $display("-------------------------");

          while(test==3)

          begin

          wait(`VLP.sys_rsc4p.alu15p.opcode==3'h1)

          $strobe("%t %d",$time,`VLP.sys_ram3p.ram[10'h2]);

          wait(`VLP.sys_rsc4p.alu15p.opcode!=3'h1);

          end

          end

          endcase

          end

          always@(`VLP.sys_rsc4p.alu15p.opcode)

          case(`VLP.sys_rsc4p.alu15p.opcode)

          3'h0 :mnemonic="HLT";

          3'h1 :mnemonic="SKZ";

          3'h2 :mnemonic="ADD";

          3'h3 :mnemonic="AND";

          3'h4 :mnemonic="XOR";

          3'h5 :mnemonic="LDA";

          3'h6 :mnemonic="STO";

          3'h7 :mnemonic="JMP";

          default : mnemonic="???";

          endcase

          endmodule

          posted on 2007-06-07 07:47 閑情萬萬 閱讀(3670) 評論(2)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 宜章县| 巩留县| 石渠县| 新化县| 咸阳市| 庆元县| 张北县| 峡江县| 新宾| 莫力| 上饶县| 类乌齐县| 新巴尔虎右旗| 元氏县| 曲阳县| 祥云县| 石泉县| 玉龙| 湘西| 沐川县| 宁明县| 九江市| 邳州市| 台东县| 邻水| 溧水县| 宜川县| 大竹县| 来安县| 曲周县| 淳化县| 东阿县| 雷波县| 当涂县| 榕江县| 喀喇沁旗| 会东县| 民乐县| 濉溪县| 资阳市| 金阳县|