⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.v

📁 简单的一个8位RISC
💻 V
📖 第 1 页 / 共 2 页
字号:
      #1;         $display ("Loading program memory with %s", "dds.rom");      $readmemh ("dds.rom", pram.mem);      fork         // Capture data         capture_data;                  // Run the clock         drive_clock;                  // Do a reset         reset_pic;                  // Monitor the number of cycles and set an absolute maximum number of cycles.         monitor_cycles (3000); // <--- this appeared about right for DDS demo to finish all bits                  // More specific monitors         //monitor_inst;         //monitor_portb;         //monitor_portc;                  // Catch end of simulation event due to max number of cycles or pattern from PIC code.         begin            @(ENDSIM);  // Catch the event.                        // Got it!            $display ("End of simulation signalled.  Killing simulation in a moment.");            #0; // Let anything else see this event...            $finish;         end      join   endendtask// *****************************  Generic Tasks  **************************  //// CYCLE monitor and end-of-simulation checker.//task monitor_cycles;   input max_cycles;      integer max_cycles;   integer cycles;   begin      cycles = 0;      fork         // Count cycles.         forever begin            @(posedge clk);            cycles = cycles + 1;         end                  // Watch for max cycles.  If we detect max cycles then throw our testbench ENDSIM event.         //         begin            wait (cycles == max_cycles);            $display ("MAXIMUM CYCLES EXCEEDED!");            ->ENDSIM;         end      join   endendtask// Generic Debug Display stuff.//task monitor_rom;   begin      forever begin         @(negedge clk);         $display ("ROM Address = %h, Data = %h", pramaddr, pramdata);      end   endendtasktask monitor_porta;   reg [7:0] last_porta;   begin      forever begin         @(negedge clk);         if (last_porta !== porta) begin            $display ("porta changes to: %h", porta);            last_porta = porta;         end      end   end         endtasktask monitor_portb;   reg [7:0] last_portb;   begin      forever begin         @(negedge clk);         if (last_portb !== portb) begin            $display ("MONITOR_PORTB: Port B changes to: %h", portb);            last_portb = portb;         end      end   endendtasktask monitor_portc;   reg [7:0] last_portc;   begin      forever begin         @(negedge clk);         if (last_portc !== portc) begin            $display ("MONITOR_PORTC: Port C changes to: %h", portc);            last_portc = portc;         end      end   endendtasktask monitor_w;   reg [7:0] last_w;   begin      forever begin         @(negedge clk);         if (debugw !== last_w) begin            $display ("W = %0h", debugw);         end         last_w = debugw;      end   endendtasktask monitor_pc;   begin      forever begin         @(negedge clk);         $display ("PC = %0h", debugpc);      end   endendtask// Monitor the INST register (e.g. the instruction) and display something// resembling a disassembler output.  We'll use several helping tasks to// look up an appopriate mnemonic.//task monitor_inst;   reg [11:0]    last_pc;   integer       opcode;   reg [8*8-1:0] mnemonic;      begin      fork         // Always keep a copy of the LAST value of the PC.  This is because         // of our pipelining.  The PC is really one value ahead.  You really         // want to see the address that corresponds to the instruction you         // are looking at.         //         forever begin            @(posedge clk);            last_pc = debugpc;         end         begin            #6;            forever begin               @(negedge clk);                              // OK.  We have an instruction.  Take this instruction and call some tasks               // to help us display a pretty output line.  We will look up a nice mnemonic, etc.               //               lookup_opcode   (debuginst, opcode);  // Look up a simpler "opcode" number instead of the actual instruction.               lookup_mnemonic (opcode, mnemonic);   // Look up the ASCII instruction name                              // Depending on the specific instruction, we want to print out different stuff.               // We may need to print out the 'K' field for literal instructions, or the 'f' field               // for the MOVF types of instruction, or only the address and mnemonic for               // simple instructions like SLEEP or CLRW.               //               if (opcode == CLRW   ||                    opcode == NOP    ||                    opcode == CLRWDT ||                   opcode == OPTION ||                   opcode == SLEEP) begin                  // These are instructions with no additional arguments.  Display the PC and MNEMONIC only.                  //                  $display ("MONITOR_INST: %h %s", last_pc, mnemonic);               end               else if (debuginst[11:10] == 2'b00) begin                  // These are the instructions with a register address.  Display the 'd' and 'f' fields.                  //                  $display ("MONITOR_INST: %h %s %0d(0x%h), %s",                      last_pc, mnemonic,                     debuginst[4:0], debuginst[4:0],                     (debuginst[5]) ? "f" : "W"                  );               end               else if (debuginst[11:10] == 2'b01) begin                  // These are the "Bit-Oriented" instructions with a bit reference and register address.                    // Display the 'b' and 'f' fields.                  //                  $display ("MONITOR_INST: %h %s bit=%d, f=%0d(0x%h)",                      last_pc, mnemonic,                     debuginst[7:5],                     debuginst[4:0], debuginst[4:0]                  );               end               else if (debuginst[11] == 1'b1) begin                  // These are the "Literal and Control" instructions with a literal field.  Display the 'k' field.                  //                  $display ("MONITOR_INST: %h %s %0d(0x%h)",                      last_pc, mnemonic,                     debuginst[7:0], debuginst[7:0]                  );               end               else begin                  $display ("MONITOR_INST: --- Unhandled instruction.. %h", debuginst);               end            end         end      join      endendtask// Given the actual 12-bit instruction, return the "opcode".  This is just an integer number// to help us handle printing and such and does NOT correspond to any hardware encoding.//task lookup_opcode;   input inst;   output opcode;      reg [11:0] inst;   integer    opcode;   begin      casex (inst)         12'b0000_0000_0000: opcode = NOP;         12'b0000_001X_XXXX: opcode = MOVWF;         12'b0000_0100_0000: opcode = CLRW;         12'b0000_011X_XXXX: opcode = CLRF;         12'b0000_10XX_XXXX: opcode = SUBWF;         12'b0000_11XX_XXXX: opcode = DECF;         12'b0001_00XX_XXXX: opcode = IORWF;         12'b0001_01XX_XXXX: opcode = ANDWF;         12'b0001_10XX_XXXX: opcode = XORWF;         12'b0001_11XX_XXXX: opcode = ADDWF;         12'b0010_00XX_XXXX: opcode = MOVF;         12'b0010_01XX_XXXX: opcode = COMF;         12'b0010_10XX_XXXX: opcode = INCF;         12'b0010_11XX_XXXX: opcode = DECFSZ;         12'b0011_00XX_XXXX: opcode = RRF;         12'b0011_01XX_XXXX: opcode = RLF;         12'b0011_10XX_XXXX: opcode = SWAPF;         12'b0011_11XX_XXXX: opcode = INCFSZ;         // *** Bit-Oriented File Register Operations         12'b0100_XXXX_XXXX: opcode = BCF;         12'b0101_XXXX_XXXX: opcode = BSF;         12'b0110_XXXX_XXXX: opcode = BTFSC;         12'b0111_XXXX_XXXX: opcode = BTFSS;         // *** Literal and Control Operations         12'b0000_0000_0010: opcode = OPTION;         12'b0000_0000_0011: opcode = SLEEP;         12'b0000_0000_0100: opcode = CLRWDT;         12'b0000_0000_0101: opcode = TRIS;         12'b0000_0000_0110: opcode = TRIS;         12'b0000_0000_0111: opcode = TRIS;         12'b1000_XXXX_XXXX: opcode = RETLW;         12'b1001_XXXX_XXXX: opcode = CALL;         12'b101X_XXXX_XXXX: opcode = GOTO;         12'b1100_XXXX_XXXX: opcode = MOVLW;         12'b1101_XXXX_XXXX: opcode = IORLW;         12'b1110_XXXX_XXXX: opcode = ANDLW;         12'b1111_XXXX_XXXX: opcode = XORLW;         default:            opcode = 0;      endcase   endendtask// Given the opcode (see task 'lookup_opcode') return the ASCII string for the instruction.//task lookup_mnemonic;   input opcode;   output mnemonic;      integer opcode;   reg [8*8-1:0]  mnemonic;   begin      case (opcode)         NOP:		mnemonic = "NOP     ";         MOVWF: 	mnemonic = "MOVWF   ";         CLRW:		mnemonic = "CLRW    ";         CLRF:		mnemonic = "CLRF    ";         SUBWF:		mnemonic = "SUBWF   ";         DECF:		mnemonic = "DECF    ";         IORWF:		mnemonic = "IORWF   ";         ANDWF:		mnemonic = "ANDWF   ";         XORWF:		mnemonic = "XORWF   ";         ADDWF:		mnemonic = "ADDWF   ";         MOVF:		mnemonic = "MOVF    ";         COMF:		mnemonic = "COMF    ";         INCF:		mnemonic = "INCF    ";         DECFSZ:	mnemonic = "DECFSZ  ";         RRF:		mnemonic = "RRF     ";         RLF:		mnemonic = "RLF     ";         SWAPF:		mnemonic = "SWAPF   ";         INCFSZ:	mnemonic = "INCFSZ  ";         // *** Bit-Oriented File Register Operations         BCF:		mnemonic = "BCF     ";         BSF:		mnemonic = "BSF     ";         BTFSC:		mnemonic = "BTFSC   ";         BTFSS:		mnemonic = "BTFSS   ";         // *** Literal and Control Operations         OPTION:	mnemonic = "OPTION  ";         SLEEP:		mnemonic = "SLEEP   ";         CLRWDT:	mnemonic = "CLRWDT  ";         TRIS: 		mnemonic = "TRIS    ";         RETLW:		mnemonic = "RETLW   ";         CALL:		mnemonic = "CALL    ";         GOTO:		mnemonic = "GOTO    ";         MOVLW:		mnemonic = "MOVLW   ";         IORLW:		mnemonic = "IORLW   ";         ANDLW:		mnemonic = "ANDLW   ";         XORLW:		mnemonic = "XORLW   ";         default:	mnemonic = "-XXXXXX-";      endcase   endendtaskendmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -