?? cpu.v
字號(hào):
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
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -