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

📄 cpu.v

📁 用Verilog 编写的8位risc cpu
💻 V
📖 第 1 页 / 共 2 页
字号:
module cpu (
   clk,
   reset,
   
   paddr,
   pdata,
   portain,
   portbout,
   portcout,
   
   expdin,
   expdout,
   expaddr,
   expread,
   expwrite,
   
   debugw,
   debugpc,
   debuginst,
   debugstatus
);

input		clk;
input		reset;

// Program memory interface
output [10:0]	paddr;
input  [11:0]	pdata;

// Basic I/O Ports
input  [7:0]	portain;
output [7:0]	portbout;
output [7:0]	portcout;

// Expansion Interface
input [7:0]	expdin;		
output [7:0]	expdout;	
output [6:0]	expaddr;	
output		expread;	
output		expwrite;	

// Debugging
output [7:0]	debugw;
output [10:0]	debugpc;
output [11:0]	debuginst;
output [7:0]	debugstatus;

// Register 
reg [10:0]	paddr;
reg [7:0]	portbout;
reg [7:0]	portcout;
reg [7:0]	expdout;
reg [6:0]	expaddr;
reg		expread;
reg		expwrite;

parameter RESET_VECTOR = 11'h7FF;

parameter	INDF_ADDRESS	= 3'h0,
		TMR0_ADDRESS	= 3'h1,
		PCL_ADDRESS	= 3'h2,
		STATUS_ADDRESS	= 3'h3,
		FSR_ADDRESS	= 3'h4,
		PORTA_ADDRESS	= 3'h5,
		PORTB_ADDRESS	= 3'h6,
		PORTC_ADDRESS	= 3'h7;

reg  [11:0]	inst;
reg  [10:0]	pc, pc_in;
reg [ 1:0]	stacklevel;
reg [10:0]	stack1;
reg [10:0]	stack2;

reg [ 7:0]	w;
reg [ 7:0]	status;

reg  [ 7:0]	fsr;

reg  [ 7:0]	tmr0;
reg  [ 7:0]	prescaler;

reg [7:0]	option;

reg [7:0]	trisa;
reg [7:0]	trisb;
reg [7:0]	trisc;

reg [7:0]	porta;	
reg [7:0]	portb;	
reg [7:0]	portc;	


reg 		skip; 

wire [ 7:0]	k;
wire [ 4:0]	fsel;
wire		d;
wire [ 2:0]	b;

reg [6:0]	fileaddr;

// Address Selects
reg		specialsel;
reg		regfilesel;
reg		expsel;

// Instruction Decoder Outputs 

wire [1:0]	aluasel;
wire [1:0]	alubsel;
wire [3:0]	aluop;

wire		zwe;
wire		cwe;

wire		isoption;
wire		istris;

wire		fwe;	
wire		wwe;	

// Bit decoder bits.  
reg [7:0]	bd;	
reg [7:0]	bdec;
wire		bdpol;	

reg [7:0]	regfilein;	
wire [7:0]	regfileout;	
reg		regfilewe;	
reg		regfilere;	

reg  [7:0]	dbus;
reg  [7:0]	sbus;


// ALU Signals
reg  [7:0]	alua;
reg  [7:0]	alub;
wire [7:0]	aluout;
wire		alucout;
wire       	aluz;

// ALU A and B mux selects.
parameter [1:0]	ALUASEL_W	= 2'b00,
		ALUASEL_SBUS	= 2'b01,
		ALUASEL_K	= 2'b10,
		ALUASEL_BD	= 2'b11;
		
parameter [1:0]	ALUBSEL_W	= 2'b00,
		ALUBSEL_SBUS	= 2'b01,
		ALUBSEL_K	= 2'b10,
		ALUBSEL_1	= 2'b11;

// ALU Operation codes.
parameter  [3:0] ALUOP_ADD  = 4'b0000;
parameter  [3:0] ALUOP_SUB  = 4'b1000;
parameter  [3:0] ALUOP_AND  = 4'b0001;
parameter  [3:0] ALUOP_OR   = 4'b0010;
parameter  [3:0] ALUOP_XOR  = 4'b0011;
parameter  [3:0] ALUOP_COM  = 4'b0100;
parameter  [3:0] ALUOP_ROR  = 4'b0101;
parameter  [3:0] ALUOP_ROL  = 4'b0110;
parameter  [3:0] ALUOP_SWAP = 4'b0111;


// Instantiate 
regs  regs (
   .clk		(clk), 
   .reset	(reset),
   .we  	(regfilewe),
   .re		(regfilere),
   .bank	(fileaddr[6:5]), 
   .location	(fileaddr[4:0]),
   .din		(regfilein), 
   .dout	(regfileout)
);

// Instatiate the ALU.
alu alu  (
   .op         (aluop), 
   .a          (alua), 
   .b          (alub),
   .y          (aluout),
   .cin        (status[0]), 
   .cout       (alucout), 
   .zout       (aluz)
);

wire		idecwwe;
wire		idecfwe;
wire		ideczwe;
wire		ideccwe;

idec idec (
   .inst     (inst),
   .aluasel  (aluasel),
   .alubsel  (alubsel),
   .aluop    (aluop),
   .wwe      (idecwwe),
   .fwe      (idecfwe),
   .zwe      (ideczwe),
   .cwe      (ideccwe),
   .bdpol    (bdpol),
   .option   (isoption),
   .tris     (istris)
);

assign wwe = idecwwe;
assign fwe = idecfwe;
assign zwe = ideczwe;
assign cwe = ideccwe;

assign	debugw = w;
assign	debugpc = pc;
assign	debuginst = inst;
assign	debugstatus = status;

// REGISTER FILE Address

always @(fsel or fsr or status) begin
   if (fsel == INDF_ADDRESS) begin
          fileaddr = fsr[6:0];
   end
   else begin
          fileaddr = {status[6:5], fsel};
   end
end
 
always @(regfilesel or fwe)
   regfilewe = regfilesel & fwe;
always @(regfilesel or aluasel or alubsel)
   regfilere = regfilesel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));

// Address Decodes

always @(fileaddr) begin
   casex (fileaddr) 

      7'bXX00XXX:
         begin
            specialsel	= 1'b1;
            regfilesel	= 1'b0;
            expsel	= 1'b0;
         end
     
      7'b11111XX: 
         begin
            specialsel	= 1'b0;
            regfilesel	= 1'b0;
            expsel	= 1'b1;
         end

      default:
         begin
            specialsel	= 1'b0;
            regfilesel	= 1'b1;
            expsel	= 1'b0;
         end
   endcase
end

// Expansion Interface

always @(dbus)
   expdout = dbus;
   
always @(fileaddr)
   expaddr = fileaddr;

always @(expsel or aluasel or alubsel)
   expread = expsel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));

always @(expsel or fwe)
   expwrite = expsel & fwe;

// SBUS 
always @(fsel or fsr or tmr0 or pc or status
         or porta or portb or portc or regfileout or expdin
         or specialsel or regfilesel or expsel) begin

   if (specialsel) begin
      case (fsel[2:0]) 
         3'h0:	sbus = fsr;
         3'h1:	sbus = tmr0;
         3'h2:	sbus = pc[7:0];
         3'h3:	sbus = status;
         3'h4:	sbus = fsr;
         3'h5:	sbus = porta; 
         3'h6:	sbus = portb; 
         3'h7:	sbus = portc;
      endcase
   end
   else begin

      if (expsel) begin
         sbus = expdin;
      end
      else begin
         if (regfilesel) begin
            sbus = regfileout;
         end
         else begin
            sbus = 8'h00;
         end
      end
   end
end
// DBUS
always @(aluout)
   dbus = aluout;

always @(dbus)
   regfilein = dbus;
   
always @(pc_in)
   paddr = pc_in;

assign k =     inst[7:0];
assign fsel  = inst[4:0];
assign d     = inst[5];
assign b     = inst[7:5];

// Bit Decoder
always @(b) begin
   case (b) 
      3'b000: bdec = 8'b00000001;
      3'b001: bdec = 8'b00000010;
      3'b010: bdec = 8'b00000100;
      3'b011: bdec = 8'b00001000;
      3'b100: bdec = 8'b00010000;
      3'b101: bdec = 8'b00100000;
      3'b110: bdec = 8'b01000000;
      3'b111: bdec = 8'b10000000;
   endcase
end

always @(bdec or bdpol)
   bd = (bdpol) ? ~bdec : bdec;

always @(posedge clk) begin
   if (reset) begin
      inst <= 12'h000;
   end
   else begin
      if (skip == 1'b1) begin
         inst <= 12'b000000000000; 
      end

⌨️ 快捷键说明

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