📄 cpu.v
字号:
// ************************************************************************// * NOVAS SOFTWARE CONFIDENTIAL PROPRIETARY NOTE *// * *// * This software contains information confidential and proprietary *// * to Novas Software Inc. It shall not be reproduced in whole *// * or in part or transferred to other documents, or disclosed *// * to third parties, or used for any purpose other than that *// * for which it was obtained, without the prior written consent *// * of Novas Software Inc. *// * (c) 1996, 1997, 1998 Novas Software Inc. *// * All rights reserved *// * *// ************************************************************************ module CPU(clock, reset, VMA, R_W, data, addr);input clock;input reset;output VMA;output R_W;inout [7:0] data;output [7:0] addr;reg VMA, R_W;parameter tHld = 5;parameter ADDRSIZE = 8;parameter WIDTH = 8;// Define the OP code`define CLRA 8'h04`define LDA 8'h14`define LDA_ 8'h18`define STA_ 8'h28`define STA 8'h2C`define ADDA 8'h34`define ADDA_ 8'h38`define SUBA 8'h48`define INCA 8'h08`define LDX 8'h54`define TAX 8'h0C`define JMP 8'h8C`define BNZ 8'h64`define Immediate 2'b00`define Absolute 2'b01`define AbsIndex 2'b10`define TEST_CARRY 2'b00`define TEST_ZERO 2'b01// Define Condition Code`define ADDRESSING mode`define CONDITION ir[WIDTH-1:WIDTH-2]`define OPCODE ir[WIDTH-1:0]`define CARRY status_reg[0]`define ZERO status_reg[1]// Define Registerwire[WIDTH-1:0] data_in;reg[WIDTH-1:0] acc,ir,index_reg,tmp_data,data_bus;reg[WIDTH:0] result;reg[ADDRSIZE-1:0] pc,addr,tmp_addr;reg[1:0] status_reg,test;assign data_in = data;assign data = R_W ? 8'hz : data_bus;always @(negedge reset) begin pc = 8'h00; R_W = 'b1; VMA = 'b1; acc = 8'h00; index_reg = 8'h00; endalways @(posedge reset) forever begin @(negedge clock) R_W = 1; addr = pc; @(negedge clock) ir = data_in; pc = pc + 1; addr = pc; @(negedge clock) casez (ir) `CLRA : begin acc = 0; set_status_reg({1'b0,acc}); end `LDA: begin fetch_operand(`Immediate, acc); set_status_reg({1'b0,acc}); end `LDA_: begin fetch_operand(`Absolute, acc); set_status_reg({1'b0,acc}); end `STA_: begin fetch_address(`Absolute, tmp_addr); write_mem(tmp_addr,acc); end `STA: begin fetch_address(`AbsIndex, tmp_addr); write_mem(tmp_addr,acc); end `ADDA: begin fetch_operand(`Immediate, tmp_data); result = acc + tmp_data; set_status_reg(result); @(posedge clock) acc = result[WIDTH-1:0]; end `ADDA_: begin fetch_operand(`Absolute, tmp_data); result = acc + tmp_data; set_status_reg(result); @(posedge clock) acc = result[WIDTH-1:0]; end `SUBA: begin fetch_operand(`Absolute, tmp_data); result = acc - tmp_data; set_status_reg(result); @(posedge clock) acc = result[WIDTH-1:0]; test = 1'b0 + 1'b1; end `INCA : begin acc = acc + 1; set_status_reg({1'b0,acc}); end `LDX: begin fetch_operand(`Immediate, tmp_data); index_reg = tmp_data; end `TAX: begin index_reg = acc; end `JMP: begin fetch_address(`Immediate, pc); end `BNZ: begin fetch_address(`Immediate, tmp_addr); if(status_reg[1] != 1'b1) pc = tmp_addr; end default: begin $display("%h OPCODE not implemented yet.", ir); $finish; end endcase endtask fetch_address;input [1:0] mode;output [WIDTH-1:0]dst;begin case (mode) `Immediate : begin @(negedge clock) dst = data_in; end `Absolute: begin @(negedge clock) pc = pc+1; @(negedge clock) dst = data_in; end `AbsIndex: begin @(negedge clock) pc = pc+1; @(negedge clock) result = data_in + index_reg; dst = result[WIDTH-1:0]; end default: begin $display("Addressing Mode %b not supported yet.", mode); $finish; end endcaseendendtasktask fetch_operand;input [1:0] mode;output [WIDTH-1:0]dst;begin @(negedge clock) case (mode) `Immediate: begin dst = data_in; pc = pc + 1; end `Absolute: begin addr = data_in; pc = pc+1; @(negedge clock) dst = data_in; end `AbsIndex: begin @(negedge clock) addr = data_in; pc = pc+1; @(negedge clock) result = data_in + index_reg; addr = result[WIDTH-1:0]; @(negedge clock) dst = data_in; end default: begin $display("Addressing Mode %b not supported yet.", mode); $finish; end endcaseendendtasktask write_mem;input[ADDRSIZE-1:0] src;input[WIDTH-1:0] d;begin @(negedge clock) addr = src; data_bus = d; R_W = 0;endendtasktask set_status_reg;input[WIDTH:0] res;begin if (res[WIDTH]) `CARRY = 1'b1; else `CARRY = 1'b0; if (res[WIDTH-1:0] == 8'h00) `ZERO = 1'b1; else `ZERO = 1'b0;endendtaskendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -