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

📄 cpu.v

📁 RISC(reduced instruction setcomputer
💻 V
📖 第 1 页 / 共 2 页
字号:
      else begin
         inst <= pdata;
      end
   end
end

// SKIP signal.
always @(inst or aluz) begin
   casex ({inst, aluz}) 
      13'b10??_????_????_?:    // A GOTO, CALL or RETLW instructions
         skip = 1'b1;
         
      13'b0110_????_????_1:    // BTFSC instruction and aluz == 1
         skip = 1'b1;
	
      13'b0111_????_????_0:    // BTFSS instruction and aluz == 0
         skip = 1'b1;
      
      13'b0010_11??_????_1:    // DECFSZ instruction and aluz == 1
         skip = 1'b1;
	
      13'b0011_11??_????_1:    // INCFSZ instruction and aluz == 1
         skip = 1'b1;
	
      default:
         skip = 1'b0;
   endcase
end

// 4:1 Data MUX into alua
always @(aluasel or w or sbus or k or bd) begin
   case (aluasel) 
      2'b00: alua = w;
      2'b01: alua = sbus;
      2'b10: alua = k;
      2'b11: alua = bd;
   endcase
end

// 4:1 Data MUX into alub
always @(alubsel or w or sbus or k) begin
   case (alubsel) 
      2'b00: alub = w;
      2'b01: alub = sbus;
      2'b10: alub = k;
      2'b11: alub = 8'b00000001;
   endcase
end
// W Register
always @(posedge clk) begin
   if (reset) begin
      w <= 8'h00;
   end
   else begin
      if (wwe) begin
         w <= dbus;
      end
   end   
end

// Writes to various Special Registers 

always @(posedge clk) begin
   if (reset) begin
      tmr0 <= 8'h00;
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == TMR0_ADDRESS)) begin
         tmr0 <= dbus;
      end
      else begin
         if (~option[5]) begin
            casex (option[3:0])  
               4'b1XXX: tmr0 <= tmr0 + 1;
               4'b0000: if (~|(prescaler & 8'b00000001)) tmr0 <= tmr0 + 1;
               4'b0001: if (~|(prescaler & 8'b00000011)) tmr0 <= tmr0 + 1;
               4'b0010: if (~|(prescaler & 8'b00000111)) tmr0 <= tmr0 + 1;
               4'b0011: if (~|(prescaler & 8'b00001111)) tmr0 <= tmr0 + 1;
               4'b0100: if (~|(prescaler & 8'b00011111)) tmr0 <= tmr0 + 1;
               4'b0101: if (~|(prescaler & 8'b00111111)) tmr0 <= tmr0 + 1;
               4'b0110: if (~|(prescaler & 8'b01111111)) tmr0 <= tmr0 + 1;
               4'b0111: if (~|(prescaler & 8'b11111111)) tmr0 <= tmr0 + 1;
            endcase            
         end
      end
   end
end

always @(posedge clk) begin
   if (reset) begin
      prescaler <= 8'h00;
   end
   else begin
      if (~option[5]) begin
         prescaler <= prescaler + 1;
      end
   end
end

// PCL Register (Register #2)
parameter STATUS_RESET_VALUE = 8'h18;

always @(posedge clk) begin
   if (reset) begin
      status <= STATUS_RESET_VALUE;
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == STATUS_ADDRESS)) begin
         status <= dbus;
      end
      else begin
         status <= {
            status[7],
            status[6],
            status[5],
            status[4],	
            status[3],	
            (zwe) ? aluz : status[2],	
                           status[1],			
            (cwe) ? alucout : status[0]	
         };
      end
   end
end
          
always @(posedge clk) begin
   if (reset) begin
      fsr <= 8'h00;
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == FSR_ADDRESS)) begin
         fsr <= dbus;
      end
   end
end

// OPTION Register

parameter OPTION_RESET_VALUE = 8'h3F;
always @(posedge clk) begin
   if (reset) begin
      option <= OPTION_RESET_VALUE;
   end
   else begin
      if (isoption)
         option <= dbus;
   end   
end

// PORTA Input Port   (Register #5)

always @(posedge clk)
   if (reset) porta <= 8'h00;
   else       porta <= portain;

// PORTB Output Port  (Register #6)
always @(posedge clk) begin
   if (reset) begin
      portb <= 8'h00;
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == PORTB_ADDRESS) & ~istris) begin
         portb <= dbus;
      end
   end   
end

// Connect the output ports to the register output.
always @(portb)
   portbout = portb;
   
// PORTC Output Port  (Register #7)
always @(posedge clk) begin
   if (reset) begin
      portc <= 8'h00;
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == PORTC_ADDRESS) & ~istris) begin
         portc <= dbus;
      end
   end   
end

always @(portc)
   portcout = portc;
 
// TRIS Registers
always @(posedge clk) begin
   if (reset) begin
      trisa <= 8'hff; 
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == PORTA_ADDRESS) & istris) begin
         trisa <= dbus;
      end
   end   
end

always @(posedge clk) begin
   if (reset) begin
      trisb <= 8'hff; 
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == PORTB_ADDRESS) & istris) begin
         trisb <= dbus;
      end
   end   
end

always @(posedge clk) begin
   if (reset) begin
      trisc <= 8'hff; 
   end
   else begin
      if (fwe & specialsel & (fileaddr[2:0] == PORTC_ADDRESS) & istris) begin
         trisc <= dbus;
      end
   end   
end
  

// PC AND STACK 

always @(posedge clk)
   if (reset) pc <= RESET_VECTOR;
   else       pc <= pc_in;

always @(inst or stacklevel or status or stack1 or stack2 or pc or dbus) begin
   casex ({inst, stacklevel}) 
      14'b101?_????_????_??: pc_in = {status[6:5],       inst[8:0]};	
      14'b1001_????_????_??: pc_in = {status[6:5], 1'b0, inst[7:0]};	
      14'b1000_????_????_00: pc_in = stack1;			
      14'b1000_????_????_01: pc_in = stack1;	
      14'b1000_????_????_10: pc_in = stack2;
      14'b1000_????_????_11: pc_in = stack2;
      14'b00?0_0010_0010_??: pc_in = {pc[10:8], dbus};	
      default:
         pc_in = pc + 1;
   endcase
end


// Implement STACK1 and STACK2 registers
always @(posedge clk) begin
   if (reset) begin
      stack1 <= 9'h000;
   end
   else begin
      if (inst[11:8] == 4'b1001) begin
         case (stacklevel) 
            2'b00:
                begin
                  stack1 <= pc;
               end
            2'b01:
                begin
                  stack2 <= pc;
               end
            2'b10:
               begin
                  $display ("Too many CALLs!!");
               end
            2'b11: 
               begin
                  $display ("Too many CALLs!!");
               end
         endcase
      end
   end
end

// Write to stacklevel
always @(posedge clk) begin
   if (reset == 1'b1) begin
      stacklevel <= 2'b00;  
   end
   else begin
      casex ({inst, stacklevel}) 
         14'b1001_????_????_00: stacklevel <= 2'b01; 
         14'b1001_????_????_01: stacklevel <= 2'b10; 
         14'b1001_????_????_10: stacklevel <= 2'b10; 
         14'b1001_????_????_11: stacklevel <= 2'b00; 

       
         14'b1000_????_????_00: stacklevel <= 2'b00; 
         14'b1000_????_????_01: stacklevel <= 2'b00; 
         14'b1000_????_????_10: stacklevel <= 2'b01; 
         14'b1000_????_????_11: stacklevel <= 2'b10; 
         default:
            stacklevel <= stacklevel;
      endcase
   end
end

// Debug Stuff 

reg [8*8-1:0] inst_string;

always @(inst) begin
   casex (inst)
      12'b0000_0000_0000: inst_string = "NOP     ";
      12'b0000_001X_XXXX: inst_string = "MOVWF   ";
      12'b0000_0100_0000: inst_string = "CLRW    ";
      12'b0000_011X_XXXX: inst_string = "CLRF    ";
      12'b0000_10XX_XXXX: inst_string = "SUBWF   ";
      12'b0000_11XX_XXXX: inst_string = "DECF    ";
      12'b0001_00XX_XXXX: inst_string = "IORWF   ";
      12'b0001_01XX_XXXX: inst_string = "ANDWF   ";
      12'b0001_10XX_XXXX: inst_string = "XORWF   ";
      12'b0001_11XX_XXXX: inst_string = "ADDWF   ";
      12'b0010_00XX_XXXX: inst_string = "MOVF    ";
      12'b0010_01XX_XXXX: inst_string = "COMF    ";
      12'b0010_10XX_XXXX: inst_string = "INCF    ";
      12'b0010_11XX_XXXX: inst_string = "DECFSZ  ";
      12'b0011_00XX_XXXX: inst_string = "RRF     ";
      12'b0011_01XX_XXXX: inst_string = "RLF     ";
      12'b0011_10XX_XXXX: inst_string = "SWAPF   ";
      12'b0011_11XX_XXXX: inst_string = "INCFSZ  ";

      // *** Bit-Oriented File Register Operations
      12'b0100_XXXX_XXXX: inst_string = "BCF     ";
      12'b0101_XXXX_XXXX: inst_string = "BSF     ";
      12'b0110_XXXX_XXXX: inst_string = "BTFSC   ";
      12'b0111_XXXX_XXXX: inst_string = "BTFSS   ";

      // *** Literal and Control Operations
      12'b0000_0000_0010: inst_string = "OPTION  ";
      12'b0000_0000_0011: inst_string = "SLEEP   ";
      12'b0000_0000_0100: inst_string = "CLRWDT  ";
      12'b0000_0000_0101: inst_string = "TRIS    ";
      12'b0000_0000_0110: inst_string = "TRIS    ";
      12'b0000_0000_0111: inst_string = "TRIS    ";
      12'b1000_XXXX_XXXX: inst_string = "RETLW   ";
      12'b1001_XXXX_XXXX: inst_string = "CALL    ";
      12'b101X_XXXX_XXXX: inst_string = "GOTO    ";
      12'b1100_XXXX_XXXX: inst_string = "MOVLW   ";
      12'b1101_XXXX_XXXX: inst_string = "IORLW   ";
      12'b1110_XXXX_XXXX: inst_string = "ANDLW   ";
      12'b1111_XXXX_XXXX: inst_string = "XORLW   ";

      default:            inst_string = "-XXXXXX-";
   endcase
end

endmodule

⌨️ 快捷键说明

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