📄 risc_core.v
字号:
///////////////////////////////////////////////////////////////////////// //////// 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 / 10psmodule 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 interfaceoutput [10:0] inst_addr;input [11:0] inst_data;// Basic I/O Portsinput [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 Registerreg 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 outputwire [7:0] src1; // ALU Source 1reg [2:0] stat_bwe; // status bits wewire 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 decodereg w_we_;reg rf_we_;reg sfr_we_;reg tris_we_;// stage 2 dst decodereg 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 Connectionswire [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 Registerreg [7:0] w; // Working Registerreg [7:0] status; // Status Registerwire [7:0] status_next;reg [6:0] fsr; // fsr register ( for indirect addressing)wire [6:0] fsr_next;reg [7:0] tmr0; // Timer 0reg [5:0] option; // Option Register// Tristate Control registers. reg [7:0] trisa;reg [7:0] trisb;reg [7:0] trisc;// I/O Port registersreg [7:0] porta_r; // PORTA input registerreg [7:0] portb_r; // PORTB input registerreg [7:0] portc_r; // PORTC input registerreg [7:0] portaout; // PORTA output registerreg [7:0] portbout; // PORTB output registerreg [7:0] portcout; // PORTC output register////////////////////////////////////////////////////////////////////////// External Reset is Synchrounous to clockalways @(posedge clk) rst <= #1 rst_in;////////////////////////////////////////////////////////////////////////// Synchrounous Register Fileregister_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 Instructionalways @(posedge clk) instr_0 <= #1 inst_data;////////////////////////////////////////////////////////////////////////// Instr Decode & Read Logicalways @(posedge clk) begin rst_r1 <= #1 rst | wdt_to; rst_r2 <= #1 rst | rst_r1 | wdt_to; endassign 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 endalways @(posedge clk) pc_r <= #1 pc; // Previous version of PC to accomodate for pipelinealways @(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; endcasemux4_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 Portassign rf_rd_bnk = fsr_next[6:5];assign rf_rd_addr = instd_zero ? fsr_next[4:0] : instr_0[4:0];// ALU OPalways @(posedge clk) casex(instr_0) // synopsys full_case parallel_case
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -