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

📄 risc_core.v

📁 pic cpu source code. it is writed in the verilog source code. it can work on the 40Mhz high speed.
💻 V
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////
////                                                             ////
////  Mini-RISC-1                                                ////
////  Mini-Risc Core                                             ////
////                                                             ////
////                                                             ////
////  Author: Rudolf Usselmann                                   ////
////          rudi@asics.ws                                      ////
////                                                             ////
////                                                             ////
////  D/L from: http://www.opencores.org/cores/minirisc/         ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
////                         www.asics.ws                        ////
////                         rudi@asics.ws                       ////
////                                                             ////
//// This source file may be used and distributed without        ////
//// restriction provided that this copyright statement is not   ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
////                                                             ////
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////

//  CVS Log
//
//  $Id: risc_core.v,v 1.3 2002/10/01 12:44:24 rudi Exp $
//
//  $Date: 2002/10/01 12:44:24 $
//  $Revision: 1.3 $
//  $Author: rudi $
//  $Locker:  $
//  $State: Exp $
//
// Change History:
//               $Log: risc_core.v,v $
//               Revision 1.3  2002/10/01 12:44:24  rudi
//               Tweaked code a bit - trying to get it run faster ...
//
//               Revision 1.2  2002/09/27 15:35:40  rudi
//               Minor update to newer devices ...
//
//
//
//
//
//
//
//
//
//
//

`timescale 1ns / 10ps

module mrisc(
   clk,
   rst_in,
   
   inst_addr,
   inst_data,

   portain,
   portbin,
   portcin,

   portaout,
   portbout,
   portcout,

   trisa,
   trisb,
   trisc,
   
   tcki,
   wdt_en );

// Basic Core I/O.
input		clk;
input		rst_in;

// Program memory interface
output [10:0]	inst_addr;
input  [11:0]	inst_data;

// Basic I/O Ports
input  [7:0]	portain;
input  [7:0]	portbin;
input  [7:0]	portcin;

output [7:0]	portaout;
output [7:0]	portbout;
output [7:0]	portcout;

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

input		tcki;
input		wdt_en;

// This should be set to the ROM location where our restart vector is.
// As set here, we have 512 words of program space.
parameter	PC_RST_VECTOR	= 11'h000,	// Should be: 11'h7FF,
		STAT_RST_VALUE	= 8'h18,
		OPT_RST_VALUE	= 8'h3f,
		FSR_RST_VALUE	= 7'h0,
		TRIS_RST_VALUE	= 8'hff;

parameter	ALU_ADD		= 4'h0,
		ALU_SUB 	= 4'h1,
		ALU_INC 	= 4'h2,
		ALU_DEC 	= 4'h3,

		ALU_AND 	= 4'h4,
		ALU_CLR 	= 4'h5,
		ALU_NOT 	= 4'h6,
		ALU_IOR 	= 4'h7,
		ALU_MOV 	= 4'h8,
		ALU_MOVW	= 4'h9,
		ALU_RLF 	= 4'ha,
		ALU_RRF 	= 4'hb,
		ALU_SWP 	= 4'hc,
		ALU_XOR 	= 4'hd,
		ALU_BCF 	= 4'he,
		ALU_BSF 	= 4'hf;

parameter	// Byte Oriented RF Operations
		I_ADDWF		= 12'b0001_11??_????,
		I_ANDWF		= 12'b0001_01??_????,
		I_CLRF		= 12'b0000_011?_????,
		I_CLRW		= 12'b0000_0100_0000,
		I_COMF		= 12'b0010_01??_????,
		I_DEC		= 12'b0000_11??_????,
		I_DECFSZ	= 12'b0010_11??_????,
		I_INCF		= 12'b0010_10??_????,
		I_INCFSZ	= 12'b0011_11??_????,
		I_IORWF		= 12'b0001_00??_????,
		I_MOV		= 12'b0010_00??_????,
		I_MOVWF		= 12'b0000_001?_????,
		I_NOP		= 12'b0000_0000_0000,
		I_RLF		= 12'b0011_01??_????,
		I_RRF		= 12'b0011_00??_????,
		I_SUBWF		= 12'b0000_10??_????,
		I_SWAPF		= 12'b0011_10??_????,
		I_XORWF		= 12'b0001_10??_????,

		// Bit Oriented RF Operations
		I_BCF		= 12'b0100_????_????,
		I_BSF		= 12'b0101_????_????,
		I_BTFSC		= 12'b0110_????_????,
		I_BTFSS		= 12'b0111_????_????,

		// Literal & Controll Operations
		I_ANDLW		= 12'b1110_????_????,
		I_CALL		= 12'b1001_????_????,
		I_CLRWDT	= 12'b0000_0000_0100,
		I_GOTO		= 12'b101?_????_????,
		I_IORLW		= 12'b1101_????_????,
		I_MOVLW		= 12'b1100_????_????,
		I_OPTION	= 12'b0000_0000_0010,
		I_RETLW		= 12'b1000_????_????,
		I_SLEEP		= 12'b0000_0000_0011,
		I_TRIS		= 12'b0000_0000_0???,
		I_XORLW		= 12'b1111_????_????;

parameter	// sfr register address encodings
		INDF_ADDR	= 3'h0,
		TMR0_ADDR	= 3'h1,
		PCL_ADDR	= 3'h2,
		STAT_ADDR	= 3'h3,
		FSR_ADDR	= 3'h4,
		PORTA_ADDR	= 3'h5,
		PORTB_ADDR	= 3'h6,
		PORTC_ADDR	= 3'h7;

parameter	// Source 1 Select
		K_SEL		= 2'b10,
		SFR_SEL 	= 2'b00,
		RF_SEL		= 2'b01;

parameter	// STATUS Register status bits we
		STAT_WR_C	= 3'b001,
		STAT_WR_DC	= 3'b010,
		STAT_WR_Z	= 3'b100;


// Instruction Register
reg		rst;
reg  [11:0]	instr_0, instr_1;
reg		rst_r1, rst_r2;
wire		valid;
reg		valid_1;

reg  [7:0]	mask;
reg  [7:0]	sfr_rd_data;
reg  [3:0]	alu_op;
reg  		src1_sel;
reg  [1:0]	src1_sel_;

wire [7:0]	dout;		// ALU output
wire [7:0]	src1;		// ALU Source 1

reg  [2:0]	stat_bwe;	// status bits we
wire		c_out, dc_out, z_out;

reg		pc_skz, pc_skz_;
reg		pc_bset, pc_bset_;
reg		pc_bclr, pc_bclr_;
reg		pc_call, pc_call_;
reg		pc_goto, pc_goto_;
reg		pc_retlw, pc_retlw_;

wire		invalidate_1;
wire		invalidate_0_;
reg		invalidate_0;

// stage 1 dst decode
reg		w_we_;
reg		rf_we_;
reg		sfr_we_;
reg		tris_we_;

// stage 2 dst decode
reg		w_we;
wire		rf_we;
reg		rf_we1, rf_we2, rf_we3;

reg		opt_we;
reg		trisa_we;
reg		trisb_we;
reg		trisc_we;

wire		indf_we_;
reg		tmr0_we;
wire		pc_we_;
reg		pc_we;
reg		stat_we;
reg		fsr_we;
reg		porta_we;
reg		portb_we;
reg		portc_we;

wire		bit_sel;
wire [7:0]	tmr0_next, tmr0_next1, tmr0_plus_1;
wire		tmr0_cnt_en;
reg		wdt_clr;
wire		wdt_to;
wire		wdt_en;
wire		tcki;

wire [7:0]	sfr_rd_data_tmp1, sfr_rd_data_tmp2, sfr_rd_data_tmp3;

// Register File Connections
wire [1:0]	rf_rd_bnk, rf_wr_bnk;
wire [4:0]	rf_rd_addr, rf_wr_addr;
wire [7:0]	rf_rd_data, rf_wr_data;

// Program Counter 
reg  [10:0]	inst_addr;
reg  [10:0]	pc;
wire [10:0]	pc_next;
wire [10:0]	pc_plus_1;
wire [10:0]	stack_out;
reg  [10:0]	pc_r, pc_r2;
wire [10:0]	pc_next1, pc_next2, pc_next3;

// W Register
reg  [7:0]	w;			// Working Register
reg  [7:0]	status;			// Status Register
wire [7:0]	status_next;
reg  [6:0]	fsr;			// fsr register ( for indirect addressing)
wire [6:0]	fsr_next;
reg  [7:0]	tmr0;			// Timer 0
reg  [5:0]	option;			// Option Register

// Tristate Control registers. 
reg [7:0]	trisa;
reg [7:0]	trisb;
reg [7:0]	trisc;

// I/O Port registers
reg [7:0]	porta_r;	// PORTA input register
reg [7:0]	portb_r;	// PORTB input register
reg [7:0]	portc_r;	// PORTC input register
reg [7:0]	portaout;	// PORTA output register
reg [7:0]	portbout;	// PORTB output register
reg [7:0]	portcout;	// PORTC output register

////////////////////////////////////////////////////////////////////////
// External Reset is Synchrounous to clock
always @(posedge clk)
	rst <= #1 rst_in;

////////////////////////////////////////////////////////////////////////
// Synchrounous Register File
register_file u0(	.clk(		clk		),
			.rst(		rst		),
			.rf_rd_bnk(	rf_rd_bnk	),
			.rf_rd_addr(	rf_rd_addr	),
			.rf_rd_data(	rf_rd_data	),
			.rf_we(		rf_we		),
			.rf_wr_bnk(	rf_wr_bnk	),
			.rf_wr_addr(	rf_wr_addr	),
			.rf_wr_data(	rf_wr_data	)
		);

////////////////////////////////////////////////////////////////////////
// Always Fetch Next Instruction
always @(posedge clk)
	instr_0 <= #1 inst_data;

////////////////////////////////////////////////////////////////////////
// Instr Decode & Read Logic

always @(posedge clk)
   begin
	rst_r1 <= #1 rst | wdt_to;
	rst_r2 <= #1 rst | rst_r1 | wdt_to;
   end

assign valid = ~rst_r2 & ~invalidate_1;
always @(posedge clk)
	valid_1 <= #1 valid;

always @(posedge clk)
   	instr_1 <= #1 instr_0;

always @(posedge clk) // Basic Decode extracted directly from the instruction
   begin
	// Mask for bit modification instructions
	case(instr_0[7:5])	// synopsys full_case parallel_case 
	   0: mask <= #1 8'h01;
	   1: mask <= #1 8'h02;
	   2: mask <= #1 8'h04;
	   3: mask <= #1 8'h08;
	   4: mask <= #1 8'h10;
	   5: mask <= #1 8'h20;
	   6: mask <= #1 8'h40;
	   7: mask <= #1 8'h80;
	endcase
   end

always @(posedge clk)
	pc_r <= #1 pc;	// Previous version of PC to accomodate for pipeline

always @(posedge clk)		// SFR Read Operands
   if(src1_sel_[1])	sfr_rd_data <= #1 instr_0[7:0];
   else
   case(instr_0[2:0])	// synopsys full_case parallel_case
      1: sfr_rd_data <= #1 tmr0_next;
      2: sfr_rd_data <= #1 pc_r[7:0];
      3: sfr_rd_data <= #1 status_next;
      4: sfr_rd_data <= #1 {1'b1, fsr_next};
      5: sfr_rd_data <= #1 porta_r;
      6: sfr_rd_data <= #1 portb_r;
      7: sfr_rd_data <= #1 portc_r;
   endcase


/*
always @(posedge clk)
	sfr_rd_data <= #1 sfr_rd_data_tmp1;


reg	[3:0]	sfr_sel;
wire	[3:0]	sfr_sel_src;

assign	sfr_sel_src = {src1_sel_[1],instr_0[2:0]};

always @(sfr_sel_src)
	casex(sfr_sel_src)	// synopsys full_case parallel_case
	   4'b1_???:	sfr_sel = 4'b01_11;
	   4'b0_001:	sfr_sel = 4'bxx_00;
	   4'b0_010:	sfr_sel = 4'b00_11;
	   4'b0_011:	sfr_sel = 4'bxx_01;
	   4'b0_100:	sfr_sel = 4'bxx_10;
	   4'b0_101:	sfr_sel = 4'b10_11;
	   4'b0_11?:	sfr_sel = 4'b11_11;
	endcase


mux4_8 u1(	.sel(sfr_sel[1:0]), .out(sfr_rd_data_tmp1),
		.in0(tmr0_next), .in1(status_next),
		.in2({1'b1, fsr_next}), .in3(sfr_rd_data_tmp2)	);

mux4_8 u2(	.sel(sfr_sel[3:2]), .out(sfr_rd_data_tmp2),
		.in0(pc_r[7:0]), .in1(instr_0[7:0]),
		.in2(porta_r), .in3(sfr_rd_data_tmp3)	);

mux2_8 u2b(	.sel(instr_0[0]), .out(sfr_rd_data_tmp3),
		.in0(portb_r), .in1(portc_r)	);
*/

reg	instd_zero;

always @(posedge clk)
	instd_zero <= #1 !(|inst_data[4:0]);

// Register File Read Port
assign rf_rd_bnk  = fsr_next[6:5];
assign rf_rd_addr = instd_zero ? fsr_next[4:0] : instr_0[4:0];

// ALU OP
always @(posedge clk)
   casex(instr_0)	// synopsys full_case parallel_case

⌨️ 快捷键说明

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