// This special monitor file is customized for the example cpu // finish when the Program Counter reaches termination address // // // (for your CPU you may need to change // 1: the termination address [99] // 2: the full path used to access PC [CPU.CPU_core.Datapath.PC] // alternatively you may wish to delete this section altogether // and rely on the simulation termination for another reason // ) // always @(posedge Clock) if ( CPU.CPU_core.Datapath.PC == 99 ) begin $display("Terminating at instruction 99\n"); @(posedge Clock); @(posedge Clock); $stop; $finish; end // the wire, assignment and function declarations below // provide text for display in the registers window of the // simulation for the example processor // // (for your CPU most of this will have to be customised) // wire [7*8:1] state_text; wire [10*8:1] sub_state_text; wire [6*8:1] OpMnemonic_text; wire [5*8:1] Function_text; wire [8*8:1] AdMode_text; wire [9*8:1] Zero_text; wire [5*8:1] WR_text; wire [13*8:1] Access_text; `ifndef no_state_view assign state_text = get_state(CPU.CPU_core.Control.state); assign sub_state_text = get_sub_state(CPU.CPU_core.Control.sub_state); `endif assign OpMnemonic_text = get_opmnemonic(CPU.CPU_core.Opcode); assign AdMode_text = get_admode(CPU.CPU_core.Opcode); assign Function_text = get_alufunc(CPU.CPU_core.Function); assign Zero_text = get_zero(CPU.CPU_core.Zflag); assign WR_text = get_wr({!RnW, !nOE}); assign Access_text = get_access({!nSelRAM, !nSelLED, !nSelSwitch}); function [7*8:1] get_state; input value; case (value) 0 : get_state = "Execute"; 1 : get_state = "Fetch"; default : get_state = "*ERR*"; endcase endfunction function [10*8:1] get_sub_state; input [1:0] sub_state; case (sub_state) 0 : get_sub_state = "Addr_Setup"; 1 : get_sub_state = "Addr_Hold"; 3 : get_sub_state = "Data_Setup"; 2 : get_sub_state = "Data_Hold"; default : get_sub_state = "*ERR*"; endcase endfunction function [6*8:1] get_opmnemonic; input [3:0] opcode; case (opcode) `NOP : get_opmnemonic = "NOP"; `JMP : get_opmnemonic = "JMP"; `JMPZ : get_opmnemonic = "JMPZ"; `JMPNZ : get_opmnemonic = "JMPNZ"; `LDA : get_opmnemonic = "LDA"; `ADD : get_opmnemonic = "ADD"; `SUB : get_opmnemonic = "SUB"; `AND : get_opmnemonic = "AND"; `OR : get_opmnemonic = "OR"; `NOT : get_opmnemonic = "NOT"; `LSL : get_opmnemonic = "LSL"; `LSR : get_opmnemonic = "LSR"; `STA : get_opmnemonic = "STA"; default : get_opmnemonic = "*ERR*"; endcase endfunction function [8*8:1] get_admode; input [3:0] opcode; case (opcode) `NOP : get_admode = "Inherent"; `JMP : get_admode = "Absolute"; `JMPZ : get_admode = "Absolute"; `JMPNZ : get_admode = "Absolute"; `LDA : get_admode = "Direct"; `ADD : get_admode = "Direct"; `SUB : get_admode = "Direct"; `AND : get_admode = "Direct"; `OR : get_admode = "Direct"; `NOT : get_admode = "Inherent"; `LSL : get_admode = "Inherent"; `LSR : get_admode = "Inherent"; `STA : get_admode = "Direct"; default : get_admode = "*ERR*"; endcase endfunction function [5*8:1] get_alufunc; input [3:0] fncode; case (fncode) `FnACC : get_alufunc = " A"; `FnMem : get_alufunc = " M"; `FnADD : get_alufunc = " A+M"; `FnSUB : get_alufunc = " A-M"; `FnAND : get_alufunc = " A&M"; `FnOR : get_alufunc = " A|M"; `FnNOT : get_alufunc = " ~A"; `FnLSL : get_alufunc = " A<<1"; `FnLSR : get_alufunc = " A>>1"; default : get_alufunc = "*ERR*"; endcase endfunction function [9*8:1] get_zero; input flag; case (flag) 0 : get_zero = "ACC<>Zero"; 1 : get_zero = "ACC==Zero"; default : get_zero = "*ERR*"; endcase endfunction function [5*8:1] get_wr; input [1:0] signal; case (signal) 2'b10 : get_wr = "write"; 2'b01 : get_wr = "read"; 2'b00 : get_wr = " "; default: get_wr = "*ERR*"; endcase endfunction function [13*8:1] get_access; input [2:0] signal; case (signal) 3'b100 : get_access = " RAM Access"; 3'b010 : get_access = " LED Access"; 3'b001 : get_access = "Switch Access"; 3'b000 : get_access = " "; default: get_access = "*ERR*"; endcase endfunction function [8:1] itoa_4; input [3:0] val; if ( val < 10 ) itoa_4="0"+val; else if ( val >= 10 ) itoa_4="A"-10+val; else itoa_4="X"; endfunction function [4*8:1] itoa; input [15:0] val; itoa = {itoa_4(val[15:12]), itoa_4(val[11:8]), itoa_4(val[7:4]), itoa_4(val[3:0])}; endfunction function [11:0] get_operand; input [15:0] instruction; get_operand = instruction[11:0]; endfunction function [6*8:1] get_mnemonic; input [15:0] instruction; get_mnemonic = get_opmnemonic(instruction[15:12]); endfunction function [1*8:1] get_digit_zero; input [15:0] number; get_digit_zero = "0" + (number%10); endfunction function [1*8:1] get_digit; input [15:0] number; if ( number > 0 ) get_digit = get_digit_zero(number); else get_digit = " "; endfunction function [11*8:1] disassemble; input [15:0] instruction; disassemble = { get_mnemonic(instruction)," ", get_digit(instruction[11:0]/1000), get_digit(instruction[11:0]/100), get_digit(instruction[11:0]/10), get_digit_zero(instruction[11:0]) }; endfunction reg [11*8:1] DisassemblyListing [ 255:0 ]; integer i; initial begin #1ns for ( i = 0; i < 256; i = i + 1 ) DisassemblyListing[i] = disassemble(RAM.Data_stored[i]); end