Formatted Version of Verilog Code
This page contains some Badly Formatted Verilog code, and its Verilog Formatted version. The output was produced by our Verilog Formatter.
Badly Formatted Verilog Code
This code is a sample taken from www.opencores.org. To be fair the original author's code was really very neat. This is identical in function to the author's, but we have disorganized the text layout to show what might happen after several harried engineers work on it in succession with their own editors, sytles, and different tab settings. This result would not be easy to work with.
///////////////////////////////////////////////////////////////////// //// //// //// Mini-RISC-1 //// //// Mini-Risc Core //// //// //// //// //// //// Author: Rudolf Usselmann //// //// [email protected] //// //// //// //// //// //// D/L from: http://www.opencores.org/cores/minirisc/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000-2002 Rudolf Usselmann //// //// www.asics.ws //// //// [email protected] //// //// //// //// 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. //// //// //// ///////////////////////////////////////////////////////////////////// `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 // Byte Oriented RF Operations I_ADDWF: alu_op <= #1 ALU_ADD; // ADDWF I_ANDWF: alu_op <= #1 ALU_AND; // ANDWF I_CLRF: alu_op <= #1 ALU_CLR; // CLRF I_CLRW: alu_op <= #1 ALU_CLR; // CLRW I_COMF: alu_op <= #1 ALU_NOT; // COMF I_DEC: alu_op <= #1 ALU_DEC; // DEC I_DECFSZ: alu_op <= #1 ALU_DEC; // DECFSZ I_INCF: alu_op <= #1 ALU_INC; // INCF I_INCFSZ: alu_op <= #1 ALU_INC; // INCFSZ I_IORWF: alu_op <= #1 ALU_IOR; // IORWF I_MOV: alu_op <= #1 ALU_MOV; // MOV I_MOVWF: alu_op <= #1 ALU_MOVW; // MOVWF I_RLF: alu_op <= #1 ALU_RLF; // RLF I_RRF: alu_op <= #1 ALU_RRF; // RRF I_SUBWF: alu_op <= #1 ALU_SUB; // SUBWF I_SWAPF: alu_op <= #1 ALU_SWP; // SWAPF I_XORWF: alu_op <= #1 ALU_XOR; // XORWF // Bit Oriented RF Operations I_BCF: alu_op <= #1 ALU_BCF; // BCF I_BSF: alu_op <= #1 ALU_BSF; // BSF // Literal & Controll Operations I_ANDLW: alu_op <= #1 ALU_AND; // ANDLW I_IORLW: alu_op <= #1 ALU_IOR; // IORLW I_MOVLW: alu_op <= #1 ALU_MOV; // MOWLW I_RETLW: alu_op <= #1 ALU_MOV; // RETLW I_XORLW: alu_op <= #1 ALU_XOR; // XORLW endcase // Source Select // This CPU source 1 can be one of: rf (or sfr) or k, // second source (if any) is always w always @(instr_0) casex(instr_0) // synopsys full_case parallel_case I_ANDLW: src1_sel_ = K_SEL;I_CALL: src1_sel_ = K_SEL; I_GOTO: src1_sel_ = K_SEL;I_IORLW: src1_sel_ = K_SEL; I_MOVLW: src1_sel_ = K_SEL;I_RETLW: src1_sel_ = K_SEL; I_XORLW: src1_sel_ = K_SEL;default: src1_sel_ = ( (instr_0[4:3]==2'h0) & (instr_0[2:0] != 3'h0 )) ? SFR_SEL : RF_SEL;endcase always @(posedge clk) src1_sel <= #1 src1_sel_[0]; // Destination Select // Destination can be one of: rf, w, option, tris OR one of sfr registers: // indf, tmr0, pc, status, fsr, porta, portb, portc, option, trisa, trisb, trisc // Stage 1 // select w, pc, rf or sfr reg w_we1, w_we1_;always @(instr_0)begin casex(instr_0) // synopsys full_case parallel_case I_ADDWF, I_ANDWF, I_COMF, I_DEC, I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF, I_MOV, I_RLF, I_RRF, I_SUBWF, I_SWAPF, I_XORWF: // w or f w_we1_ = 1; default: w_we1_ = 0; endcase end always @(instr_0) begin w_we_ = 0; rf_we_ = 0; sfr_we_ = 0;tris_we_= 0; casex(instr_0) // synopsys full_case parallel_case I_ADDWF, I_ANDWF, I_COMF, I_DEC, I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF, I_MOV, I_RLF, I_RRF, I_SUBWF, I_SWAPF, I_XORWF: // w or f begin rf_we_ = instr_0[5] & (instr_0[4] | instr_0[3]); sfr_we_ = instr_0[5] & ~instr_0[4] & ~instr_0[3]; end I_MOVWF, I_CLRF, I_BCF, I_BSF: // only f begin rf_we_ = instr_0[4] | instr_0[3]; sfr_we_ = ~instr_0[4] & ~instr_0[3];end I_CLRW, I_IORLW, I_MOVLW, I_ANDLW, I_RETLW, I_XORLW: w_we_ = 1; // only w I_TRIS: tris_we_ = 1; // trisa or trisb or trisc endcase end assign indf_we_ = sfr_we_ & (instr_0[2:0] == INDF_ADDR);assign pc_we_ = sfr_we_ & (instr_0[2:0] == PCL_ADDR); // Stage 2 destination encoder // write enable outputs are registered now always @(posedge clk) w_we <= #1 w_we_; // working register write 0 enable always @(posedge clk) w_we1 <= #1 w_we1_; // working register write 1 enable // Register File Write Enable is composed of thee conditions: 1) direct register writing (0x10-0x1f); // 2) Direct Global Register writing (0x08-0x0f), and 3) Indirect Register File Writing // The logic has been partitioned and balanced between the decode and execute stage ... assign rf_we = rf_we1 | (rf_we2 & rf_we3); // register file write enable Composite always @(posedge clk)rf_we1 <= #1 valid & rf_we_; // register file write enable 1 always @(posedge clk)rf_we2 <= #1 valid & (fsr_next[4] | fsr_next[3]);// register file write enable 2 always @(posedge clk)rf_we3 <= #1 indf_we_; // register file write enable 3 always @(posedge clk)wdt_clr <= #1 instr_0[11:0] == I_CLRWDT; always @(posedge clk) opt_we <= #1 instr_0[11:0] == I_OPTION; always @(posedge clk) trisa_we <= #1 tris_we_ & (instr_0[2:0] == PORTA_ADDR);always @(posedge clk) trisb_we <= #1 tris_we_ & (instr_0[2:0] == PORTB_ADDR);always @(posedge clk) trisc_we <= #1 tris_we_ & (instr_0[2:0] == PORTC_ADDR);always @(posedge clk) begin // SFR registers tmr0_we <= #1 sfr_we_ & (instr_0[2:0] == TMR0_ADDR); pc_we <= #1 valid & pc_we_; stat_we <= #1 valid & sfr_we_ & (instr_0[2:0] == STAT_ADDR); fsr_we <= #1 valid & sfr_we_ & (instr_0[2:0] == FSR_ADDR); porta_we <= #1 sfr_we_ & (instr_0[2:0] == PORTA_ADDR);portb_we <= #1 sfr_we_ & (instr_0[2:0] == PORTB_ADDR); portc_we <= #1 sfr_we_ & (instr_0[2:0] == PORTC_ADDR); end // Instructions that directly modify PC always @(instr_0) begin pc_skz_ = 0;pc_bset_ = 0;pc_bclr_ = 0; pc_call_ = 0; pc_goto_ = 0; pc_retlw_ = 0; casex(instr_0) // synopsys full_case parallel_case // Byte Oriented RF Operations I_DECFSZ,I_INCFSZ: pc_skz_ = 1; // Bit Oriented RF Operations I_BTFSS: pc_bset_ = 1;I_BTFSC: pc_bclr_ = 1; // Literal & Controll Operations I_CALL: pc_call_ = 1;I_GOTO: pc_goto_ = 1;I_RETLW: pc_retlw_ = 1;endcase end always @(posedge clk) begin pc_skz <= #1 valid & pc_skz_;pc_bset <= #1 valid & pc_bset_; pc_bclr <= #1 valid & pc_bclr_;pc_call <= #1 valid & pc_call_; pc_goto <= #1 valid & pc_goto_;pc_retlw <= #1 valid & pc_retlw_; end assign invalidate_0_ = (pc_call_ | pc_goto_ | pc_retlw_ | pc_we_); always @ (posedge clk) invalidate_0 <= #1 invalidate_0_; // Status bits WE always @(posedge clk)begin stat_bwe <= #1 0;if(valid) casex(instr_0) // synopsys full_case parallel_case // Byte Oriented RF Operations I_ADDWF: stat_bwe <= #1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z; I_ANDWF: stat_bwe <= #1 STAT_WR_Z; I_CLRF: stat_bwe <= #1 STAT_WR_Z; I_CLRW: stat_bwe <= #1 STAT_WR_Z; I_COMF: stat_bwe <= #1 STAT_WR_Z; I_DEC: stat_bwe <= #1 STAT_WR_Z; I_INCF: stat_bwe <= #1 STAT_WR_Z; I_IORWF: stat_bwe <= #1 STAT_WR_Z; I_MOV: stat_bwe <= #1 STAT_WR_Z; I_RLF: stat_bwe <= #1 STAT_WR_C; I_RRF: stat_bwe <= #1 STAT_WR_C; I_SUBWF: stat_bwe <= #1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z; I_XORWF: stat_bwe <= #1 STAT_WR_Z; // Literal & Controll Operations I_ANDLW: stat_bwe <= #1 STAT_WR_Z;//I_CLRWDT: // Modifies TO & PD *** FIX ME *** I_IORLW: stat_bwe <= #1 STAT_WR_Z; //I_SLEEP: // Modifies TO & PD *** FIX ME *** I_XORLW: stat_bwe <= #1 STAT_WR_Z; endcase end //////////////////////////////////////////////////////////////////////// // Wr & Execute Logic (including PC) // Second Pipeline Stage //////////////////////////////////////////////////////////////////////// // Source OP Sel //assign src1 = src1_sel ? rf_rd_data : sfr_rd_data; mux2_8 u3( .sel(src1_sel), .in0(sfr_rd_data), .in1(rf_rd_data), .out(src1) ); alu u4(.s1(src1),.s2(w),.mask(mask),.out(dout),.op(alu_op),.c_in(status[0]),.c(c_out),.dc(dc_out),.z(z_out) ); // Register file connections assign rf_wr_bnk = fsr[6:5];assign rf_wr_addr = (instr_1[4:0]==0) ? fsr[4:0] : instr_1[4:0]; assign rf_wr_data = dout;wire [7:0] status_next2; // Deal with all special registers (SFR) writes /* always @(rst or status or stat_we or stat_bwe or dout or c_out or dc_out or z_out) if(rst) status_next = STAT_RST_VALUE; else begin status_next = status; // Default Keep Value if(stat_we) status_next = dout | 8'h18; else begin if(stat_bwe[0]) status_next[0] = c_out; if(stat_bwe[1]) status_next[1] = dc_out; if(stat_bwe[2]) status_next[2] = z_out; end end */ assign status_next2[0] = stat_bwe[0] ? c_out : status[0]; assign status_next2[1] = stat_bwe[1] ? dc_out : status[1]; assign status_next2[2] = stat_bwe[2] ? z_out : status[2]; mux2_8 u21( .sel(stat_we), .in1( {dout | 8'h18} ), .in0( {status[7:3],status_next2[2:0]} ), .out(status_next) ); always @(posedge clk) if(rst) status <= #1 STAT_RST_VALUE;else status <= #1 status_next; //assign fsr_next = fsr_we ? dout[6:0] : fsr; mux2_7 u31( .sel(fsr_we), .in1(dout[6:0]), .in0(fsr), .out(fsr_next) ); always @(posedge clk) if(rst) fsr <= #1 FSR_RST_VALUE;else fsr <= #1 fsr_next;always @(posedge clk) if(valid_1 & (w_we | (w_we1 & ~instr_1[5])) ) w <= #1 dout;always @(posedge clk) if(rst) trisa <= #1 TRIS_RST_VALUE;else if(trisa_we & valid_1) trisa <= #1 w;always @(posedge clk) if(rst) trisb <= #1 TRIS_RST_VALUE;else if(trisb_we & valid_1) trisb <= #1 w;always @(posedge clk) if(rst) trisc <= #1 TRIS_RST_VALUE;else if(trisc_we & valid_1) trisc <= #1 w;always @(posedge clk) if(rst) option <= #1 OPT_RST_VALUE;else if(opt_we & valid_1 ) option <= #1 w[5:0];always @(posedge clk) if(porta_we & valid_1) portaout <= #1 dout;always @(posedge clk) if(portb_we & valid_1) portbout <= #1 dout;always @(posedge clk) if(portc_we & valid_1) portcout <= #1 dout;always @(posedge clk) begin porta_r <= #1 portain;portb_r <= #1 portbin;portc_r <= #1 portcin;end /////////////////////////////////////////////////////////////////////// // Timer Logic //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? tmr0_plus_1 : tmr0; //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? (tmr0 + 1) : tmr0; mux2_8 u5( .sel(tmr0_we & valid_1), .in0(tmr0_next1), .in1(dout), .out(tmr0_next) ); mux2_8 u6( .sel(tmr0_cnt_en), .in0(tmr0), .in1(tmr0_plus_1), .out(tmr0_next1) ); inc8 u7( .in(tmr0), .out(tmr0_plus_1) ); always @(posedge clk) tmr0 <= #1 tmr0_next; presclr_wdt u8( .clk( clk ), .rst( rst ),.tcki( tcki ), .option( option[5:0] ),.tmr0_we( tmr0_we & valid_1 ), .tmr0_cnt_en( tmr0_cnt_en ),.wdt_en( wdt_en ), .wdt_clr( wdt_clr & valid_1 ), .wdt_to( wdt_to ) ); //////////////////////////////////////////////////////////////////////// // Programm Counter Logic always @(posedge clk) pc_r2 <= #1 pc_r; // 'inst_addr' is a duplication of the 'pc'. The only time when it is really needed // is when the program memory is not on the chip and we want to place the registers // directly in the IO pads to reduce Tcq (For example in a Xilinx FPGA implementation). // If the program memory is on the chip or if the implmentation allows feedback from // registers in the IO cells, this is not needed. Synopsys FPGA compiler appears to // make the correct decission either way, and gett rid of unneded logic ... always @(posedge clk) if(rst) inst_addr <= #1 PC_RST_VECTOR;else inst_addr <= #1 pc_next; always @( posedge clk)if(rst) pc <= #1 PC_RST_VECTOR; else pc <= #1 pc_next; /* always @(pc_plus_1 or dout or pc_we or status or stack_out or pc_call or pc_goto or pc_retlw or instr_1) if(pc_we)pc_next={status[6:5],1'b0,dout}; else if(!pc_call&!pc_goto&!pc_retlw)pc_next=pc_plus_1;else if(pc_call)pc_next={status[6:5],1'b0,instr_1[7:0]}; else if(pc_goto)pc_next={status[6:5],instr_1[8:0]}; else if(pc_retlw)pc_next=stack_out; */ wire [10:0] pc_tmp1, pc_tmp2, pc_tmp3;wire pc_sel1; assign pc_tmp1 = {status[6:5], 1'b0, dout[7:0]};assign pc_tmp2 = {status[6:5], 1'b0, instr_1[7:0]}; assign pc_tmp3 = {status[6:5], instr_1[8:0]}; assign pc_sel1 = (!pc_call & !pc_goto & !pc_retlw); mux2_11 u9 ( .sel(pc_we), .in0(pc_next1), .in1(pc_tmp1), .out(pc_next) ); mux2_11 u10( .sel(pc_sel1), .in0(pc_next2), .in1(pc_plus_1), .out(pc_next1) );mux2_11 u11( .sel(pc_call), .in0(pc_next3), .in1(pc_tmp2), .out(pc_next2) ); mux2_11 u12( .sel(pc_goto), .in0(stack_out), .in1(pc_tmp3), .out(pc_next3) ); inc11 u13( .in(pc), .out(pc_plus_1) );reg invalidate_1_r1, invalidate_1_r2; assign invalidate_1 = (pc_skz & z_out) | (pc_bset & bit_sel) | (pc_bclr & !bit_sel) | (invalidate_0 & valid_1) | invalidate_1_r1; always @(posedge clk)begin invalidate_1_r1 <= #1 (invalidate_0 & valid_1) | invalidate_1_r2; invalidate_1_r2 <= #1 (invalidate_0 & valid_1);end //assign bit_sel = src1[ instr_1[7:5] ]; mux8_1 u22( .sel(instr_1[7:5]), .in(src1), .out(bit_sel) ); sfifo4x11 u14( .clk(clk), .push(pc_call), .din(pc_r2), .pop(pc_retlw), .dout(stack_out) );endmodule
Verilog Formatted Version
This is the result of using SD's VerilogFormatter tool on the sample badly formatted Verilog , using just the default settings. You can see that the formatter has chosen very different line breaks, based on the language structure. The block structure is now clearly visible. An engineer might actually be able to work on this version.
///////////////////////////////////////////////////////////////////// //// //// //// Mini-RISC-1 //// //// Mini-Risc Core //// //// //// //// //// //// Author: Rudolf Usselmann //// //// [email protected] //// //// //// //// //// //// D/L from: http://www.opencores.org/cores/minirisc/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000-2002 Rudolf Usselmann //// //// www.asics.ws //// //// [email protected] //// //// //// //// 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. //// //// //// ///////////////////////////////////////////////////////////////////// // `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 // Byte Oriented RF Operations I_ADDWF : alu_op <= # 1 ALU_ADD; // ADDWF I_ANDWF : alu_op <= # 1 ALU_AND; // ANDWF I_CLRF : alu_op <= # 1 ALU_CLR; // CLRF I_CLRW : alu_op <= # 1 ALU_CLR; // CLRW I_COMF : alu_op <= # 1 ALU_NOT; // COMF I_DEC : alu_op <= # 1 ALU_DEC; // DEC I_DECFSZ : alu_op <= # 1 ALU_DEC; // DECFSZ I_INCF : alu_op <= # 1 ALU_INC; // INCF I_INCFSZ : alu_op <= # 1 ALU_INC; // INCFSZ I_IORWF : alu_op <= # 1 ALU_IOR; // IORWF I_MOV : alu_op <= # 1 ALU_MOV; // MOV I_MOVWF : alu_op <= # 1 ALU_MOVW; // MOVWF I_RLF : alu_op <= # 1 ALU_RLF; // RLF I_RRF : alu_op <= # 1 ALU_RRF; // RRF I_SUBWF : alu_op <= # 1 ALU_SUB; // SUBWF I_SWAPF : alu_op <= # 1 ALU_SWP; // SWAPF I_XORWF : alu_op <= # 1 ALU_XOR; // XORWF // Bit Oriented RF Operations I_BCF : alu_op <= # 1 ALU_BCF; // BCF I_BSF : alu_op <= # 1 ALU_BSF; // BSF // Literal & Controll Operations I_ANDLW : alu_op <= # 1 ALU_AND; // ANDLW I_IORLW : alu_op <= # 1 ALU_IOR; // IORLW I_MOVLW : alu_op <= # 1 ALU_MOV; // MOWLW I_RETLW : alu_op <= # 1 ALU_MOV; // RETLW I_XORLW : alu_op <= # 1 ALU_XOR; // XORLW endcase // Source Select // This CPU source 1 can be one of: rf (or sfr) or k, // second source (if any) is always w always @(instr_0) casex (instr_0) // synopsys full_case parallel_case I_ANDLW : src1_sel_ = K_SEL; I_CALL : src1_sel_ = K_SEL; I_GOTO : src1_sel_ = K_SEL; I_IORLW : src1_sel_ = K_SEL; I_MOVLW : src1_sel_ = K_SEL; I_RETLW : src1_sel_ = K_SEL; I_XORLW : src1_sel_ = K_SEL; default : src1_sel_ = ((instr_0[4 : 3] == 2'h0) & (instr_0[2 : 0] != 3'h0)) ? SFR_SEL : RF_SEL; endcase always @(posedge clk) src1_sel <= # 1 src1_sel_[0]; // Destination Select // Destination can be one of: rf, w, option, tris OR one of sfr registers: // indf, tmr0, pc, status, fsr, porta, portb, portc, option, trisa, trisb, trisc // Stage 1 // select w, pc, rf or sfr reg w_we1, w_we1_; always @(instr_0) begin casex (instr_0) // synopsys full_case parallel_case I_ADDWF, I_ANDWF, I_COMF, I_DEC, I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF, I_MOV, I_RLF, I_RRF, I_SUBWF, I_SWAPF, I_XORWF : // w or f w_we1_ = 1; default : w_we1_ = 0; endcase end always @(instr_0) begin w_we_ = 0; rf_we_ = 0; sfr_we_ = 0; tris_we_ = 0; casex (instr_0) // synopsys full_case parallel_case I_ADDWF, I_ANDWF, I_COMF, I_DEC, I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF, I_MOV, I_RLF, I_RRF, I_SUBWF, I_SWAPF, I_XORWF : // w or f begin rf_we_ = instr_0[5] & (instr_0[4] | instr_0[3]); sfr_we_ = instr_0[5] & ~ instr_0[4] & ~ instr_0[3]; end I_MOVWF, I_CLRF, I_BCF, I_BSF : // only f begin rf_we_ = instr_0[4] | instr_0[3]; sfr_we_ = ~ instr_0[4] & ~ instr_0[3]; end I_CLRW, I_IORLW, I_MOVLW, I_ANDLW, I_RETLW, I_XORLW : w_we_ = 1; // only w I_TRIS : tris_we_ = 1; // trisa or trisb or trisc endcase end assign indf_we_ = sfr_we_ & (instr_0[2 : 0] == INDF_ADDR); assign pc_we_ = sfr_we_ & (instr_0[2 : 0] == PCL_ADDR); // Stage 2 destination encoder // write enable outputs are registered now always @(posedge clk) w_we <= # 1 w_we_; // working register write 0 enable always @(posedge clk) w_we1 <= # 1 w_we1_; // working register write 1 enable // Register File Write Enable is composed of thee conditions: 1) direct register writing (0x10-0x1f); // 2) Direct Global Register writing (0x08-0x0f), and 3) Indirect Register File Writing // The logic has been partitioned and balanced between the decode and execute stage ... assign rf_we = rf_we1 | (rf_we2 & rf_we3); // register file write enable Composite always @(posedge clk) rf_we1 <= # 1 valid & rf_we_; // register file write enable 1 always @(posedge clk) rf_we2 <= # 1 valid & (fsr_next[4] | fsr_next[3]); // register file write enable 2 always @(posedge clk) rf_we3 <= # 1 indf_we_; // register file write enable 3 always @(posedge clk) wdt_clr <= # 1 instr_0[11 : 0] == I_CLRWDT; always @(posedge clk) opt_we <= # 1 instr_0[11 : 0] == I_OPTION; always @(posedge clk) trisa_we <= # 1 tris_we_ & (instr_0[2 : 0] == PORTA_ADDR); always @(posedge clk) trisb_we <= # 1 tris_we_ & (instr_0[2 : 0] == PORTB_ADDR); always @(posedge clk) trisc_we <= # 1 tris_we_ & (instr_0[2 : 0] == PORTC_ADDR); always @(posedge clk) begin // SFR registers tmr0_we <= # 1 sfr_we_ & (instr_0[2 : 0] == TMR0_ADDR); pc_we <= # 1 valid & pc_we_; stat_we <= # 1 valid & sfr_we_ & (instr_0[2 : 0] == STAT_ADDR); fsr_we <= # 1 valid & sfr_we_ & (instr_0[2 : 0] == FSR_ADDR); porta_we <= # 1 sfr_we_ & (instr_0[2 : 0] == PORTA_ADDR); portb_we <= # 1 sfr_we_ & (instr_0[2 : 0] == PORTB_ADDR); portc_we <= # 1 sfr_we_ & (instr_0[2 : 0] == PORTC_ADDR); end // Instructions that directly modify PC always @(instr_0) begin pc_skz_ = 0; pc_bset_ = 0; pc_bclr_ = 0; pc_call_ = 0; pc_goto_ = 0; pc_retlw_ = 0; casex (instr_0) // synopsys full_case parallel_case // Byte Oriented RF Operations I_DECFSZ, I_INCFSZ : pc_skz_ = 1; // Bit Oriented RF Operations I_BTFSS : pc_bset_ = 1; I_BTFSC : pc_bclr_ = 1; // Literal & Controll Operations I_CALL : pc_call_ = 1; I_GOTO : pc_goto_ = 1; I_RETLW : pc_retlw_ = 1; endcase end always @(posedge clk) begin pc_skz <= # 1 valid & pc_skz_; pc_bset <= # 1 valid & pc_bset_; pc_bclr <= # 1 valid & pc_bclr_; pc_call <= # 1 valid & pc_call_; pc_goto <= # 1 valid & pc_goto_; pc_retlw <= # 1 valid & pc_retlw_; end assign invalidate_0_ = (pc_call_ | pc_goto_ | pc_retlw_ | pc_we_); always @(posedge clk) invalidate_0 <= # 1 invalidate_0_; // Status bits WE always @(posedge clk) begin stat_bwe <= # 1 0; if (valid) casex (instr_0) // synopsys full_case parallel_case // Byte Oriented RF Operations I_ADDWF : stat_bwe <= # 1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z; I_ANDWF : stat_bwe <= # 1 STAT_WR_Z; I_CLRF : stat_bwe <= # 1 STAT_WR_Z; I_CLRW : stat_bwe <= # 1 STAT_WR_Z; I_COMF : stat_bwe <= # 1 STAT_WR_Z; I_DEC : stat_bwe <= # 1 STAT_WR_Z; I_INCF : stat_bwe <= # 1 STAT_WR_Z; I_IORWF : stat_bwe <= # 1 STAT_WR_Z; I_MOV : stat_bwe <= # 1 STAT_WR_Z; I_RLF : stat_bwe <= # 1 STAT_WR_C; I_RRF : stat_bwe <= # 1 STAT_WR_C; I_SUBWF : stat_bwe <= # 1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z; I_XORWF : stat_bwe <= # 1 STAT_WR_Z; // Literal & Controll Operations I_ANDLW : stat_bwe <= # 1 STAT_WR_Z; //I_CLRWDT: // Modifies TO & PD *** FIX ME *** I_IORLW : stat_bwe <= # 1 STAT_WR_Z; //I_SLEEP: // Modifies TO & PD *** FIX ME *** I_XORLW : stat_bwe <= # 1 STAT_WR_Z; endcase end //////////////////////////////////////////////////////////////////////// // Wr & Execute Logic (including PC) // Second Pipeline Stage //////////////////////////////////////////////////////////////////////// // Source OP Sel //assign src1 = src1_sel ? rf_rd_data : sfr_rd_data; mux2_8 u3(.sel(src1_sel), .in0(sfr_rd_data), .in1(rf_rd_data), .out(src1)); alu u4(.s1(src1), .s2(w), .mask(mask), .out(dout), .op(alu_op), .c_in(status[0]), .c(c_out), .dc(dc_out), .z(z_out)); // Register file connections assign rf_wr_bnk = fsr[6 : 5]; assign rf_wr_addr = (instr_1[4 : 0] == 0) ? fsr[4 : 0] : instr_1[4 : 0]; assign rf_wr_data = dout; wire [7 : 0] status_next2; // Deal with all special registers (SFR) writes /* always @(rst or status or stat_we or stat_bwe or dout or c_out or dc_out or z_out) if(rst) status_next = STAT_RST_VALUE; else begin status_next = status; // Default Keep Value if(stat_we) status_next = dout | 8'h18; else begin if(stat_bwe[0]) status_next[0] = c_out; if(stat_bwe[1]) status_next[1] = dc_out; if(stat_bwe[2]) status_next[2] = z_out; end end */ assign status_next2[0] = stat_bwe[0] ? c_out : status[0]; assign status_next2[1] = stat_bwe[1] ? dc_out : status[1]; assign status_next2[2] = stat_bwe[2] ? z_out : status[2]; mux2_8 u21(.sel(stat_we), .in1({ dout | 8'h18 }), .in0({ status[7 : 3], status_next2[2 : 0]}), .out(status_next)); always @(posedge clk) if (rst) status <= # 1 STAT_RST_VALUE; else status <= # 1 status_next; //assign fsr_next = fsr_we ? dout[6:0] : fsr; mux2_7 u31(.sel(fsr_we), .in1(dout[6 : 0]), .in0(fsr), .out(fsr_next)); always @(posedge clk) if (rst) fsr <= # 1 FSR_RST_VALUE; else fsr <= # 1 fsr_next; always @(posedge clk) if (valid_1 & (w_we | (w_we1 & ~ instr_1[5]))) w <= # 1 dout; always @(posedge clk) if (rst) trisa <= # 1 TRIS_RST_VALUE; else if (trisa_we & valid_1) trisa <= # 1 w; always @(posedge clk) if (rst) trisb <= # 1 TRIS_RST_VALUE; else if (trisb_we & valid_1) trisb <= # 1 w; always @(posedge clk) if (rst) trisc <= # 1 TRIS_RST_VALUE; else if (trisc_we & valid_1) trisc <= # 1 w; always @(posedge clk) if (rst) option <= # 1 OPT_RST_VALUE; else if (opt_we & valid_1) option <= # 1 w[5 : 0]; always @(posedge clk) if (porta_we & valid_1) portaout <= # 1 dout; always @(posedge clk) if (portb_we & valid_1) portbout <= # 1 dout; always @(posedge clk) if (portc_we & valid_1) portcout <= # 1 dout; always @(posedge clk) begin porta_r <= # 1 portain; portb_r <= # 1 portbin; portc_r <= # 1 portcin; end /////////////////////////////////////////////////////////////////////// // Timer Logic //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? tmr0_plus_1 : tmr0; //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? (tmr0 + 1) : tmr0; mux2_8 u5(.sel(tmr0_we & valid_1), .in0(tmr0_next1), .in1(dout), .out(tmr0_next)); mux2_8 u6(.sel(tmr0_cnt_en), .in0(tmr0), .in1(tmr0_plus_1), .out(tmr0_next1)); inc8 u7(.in(tmr0), .out(tmr0_plus_1)); always @(posedge clk) tmr0 <= # 1 tmr0_next; presclr_wdt u8(.clk(clk), .rst(rst), .tcki(tcki), .option(option[5 : 0]), .tmr0_we(tmr0_we & valid_1), .tmr0_cnt_en(tmr0_cnt_en), .wdt_en(wdt_en), .wdt_clr(wdt_clr & valid_1), .wdt_to(wdt_to)); //////////////////////////////////////////////////////////////////////// // Programm Counter Logic always @(posedge clk) pc_r2 <= # 1 pc_r; // 'inst_addr' is a duplication of the 'pc'. The only time when it is really needed // is when the program memory is not on the chip and we want to place the registers // directly in the IO pads to reduce Tcq (For example in a Xilinx FPGA implementation). // If the program memory is on the chip or if the implmentation allows feedback from // registers in the IO cells, this is not needed. Synopsys FPGA compiler appears to // make the correct decission either way, and gett rid of unneded logic ... always @(posedge clk) if (rst) inst_addr <= # 1 PC_RST_VECTOR; else inst_addr <= # 1 pc_next; always @(posedge clk) if (rst) pc <= # 1 PC_RST_VECTOR; else pc <= # 1 pc_next; /* always @(pc_plus_1 or dout or pc_we or status or stack_out or pc_call or pc_goto or pc_retlw or instr_1) if(pc_we) pc_next = {status[6:5], 1'b0, dout}; else if(!pc_call & !pc_goto & !pc_retlw) pc_next = pc_plus_1; else if(pc_call) pc_next = {status[6:5], 1'b0, instr_1[7:0]}; else if(pc_goto) pc_next = {status[6:5], instr_1[8:0]}; else if(pc_retlw) pc_next = stack_out; */ wire [10 : 0] pc_tmp1, pc_tmp2, pc_tmp3; wire pc_sel1; assign pc_tmp1 = { status[6 : 5], 1'b0, dout[7 : 0]}; assign pc_tmp2 = { status[6 : 5], 1'b0, instr_1[7 : 0]}; assign pc_tmp3 = { status[6 : 5], instr_1[8 : 0]}; assign pc_sel1 = (! pc_call & ! pc_goto & ! pc_retlw); mux2_11 u9(.sel(pc_we), .in0(pc_next1), .in1(pc_tmp1), .out(pc_next)); mux2_11 u10(.sel(pc_sel1), .in0(pc_next2), .in1(pc_plus_1), .out(pc_next1)); mux2_11 u11(.sel(pc_call), .in0(pc_next3), .in1(pc_tmp2), .out(pc_next2)); mux2_11 u12(.sel(pc_goto), .in0(stack_out), .in1(pc_tmp3), .out(pc_next3)); inc11 u13(.in(pc), .out(pc_plus_1)); reg invalidate_1_r1, invalidate_1_r2; assign invalidate_1 = (pc_skz & z_out) | (pc_bset & bit_sel) | (pc_bclr & ! bit_sel) | (invalidate_0 & valid_1) | invalidate_1_r1; always @(posedge clk) begin invalidate_1_r1 <= # 1 (invalidate_0 & valid_1) | invalidate_1_r2; invalidate_1_r2 <= # 1 (invalidate_0 & valid_1); end //assign bit_sel = src1[ instr_1[7:5] ]; mux8_1 u22(.sel(instr_1[7 : 5]), .in(src1), .out(bit_sel)); sfifo4x11 u14(.clk(clk), .push(pc_call), .din(pc_r2), .pop(pc_retlw), .dout(stack_out)); endmodule