?? cpu.v
字號:
module cpu (
clk,
reset,
paddr,
pdata,
portain,
portbout,
portcout,
expdin,
expdout,
expaddr,
expread,
expwrite,
debugw,
debugpc,
debuginst,
debugstatus
);
input clk;
input reset;
// Program memory interface
output [10:0] paddr;
input [11:0] pdata;
// Basic I/O Ports
input [7:0] portain;
output [7:0] portbout;
output [7:0] portcout;
// Expansion Interface
input [7:0] expdin;
output [7:0] expdout;
output [6:0] expaddr;
output expread;
output expwrite;
// Debugging
output [7:0] debugw;
output [10:0] debugpc;
output [11:0] debuginst;
output [7:0] debugstatus;
// Register
reg [10:0] paddr;
reg [7:0] portbout;
reg [7:0] portcout;
reg [7:0] expdout;
reg [6:0] expaddr;
reg expread;
reg expwrite;
parameter RESET_VECTOR = 11'h7FF;
parameter INDF_ADDRESS = 3'h0,
TMR0_ADDRESS = 3'h1,
PCL_ADDRESS = 3'h2,
STATUS_ADDRESS = 3'h3,
FSR_ADDRESS = 3'h4,
PORTA_ADDRESS = 3'h5,
PORTB_ADDRESS = 3'h6,
PORTC_ADDRESS = 3'h7;
reg [11:0] inst;
reg [10:0] pc, pc_in;
reg [ 1:0] stacklevel;
reg [10:0] stack1;
reg [10:0] stack2;
reg [ 7:0] w;
reg [ 7:0] status;
reg [ 7:0] fsr;
reg [ 7:0] tmr0;
reg [ 7:0] prescaler;
reg [7:0] option;
reg [7:0] trisa;
reg [7:0] trisb;
reg [7:0] trisc;
reg [7:0] porta;
reg [7:0] portb;
reg [7:0] portc;
reg skip;
wire [ 7:0] k;
wire [ 4:0] fsel;
wire d;
wire [ 2:0] b;
reg [6:0] fileaddr;
// Address Selects
reg specialsel;
reg regfilesel;
reg expsel;
// Instruction Decoder Outputs
wire [1:0] aluasel;
wire [1:0] alubsel;
wire [3:0] aluop;
wire zwe;
wire cwe;
wire isoption;
wire istris;
wire fwe;
wire wwe;
// Bit decoder bits.
reg [7:0] bd;
reg [7:0] bdec;
wire bdpol;
reg [7:0] regfilein;
wire [7:0] regfileout;
reg regfilewe;
reg regfilere;
reg [7:0] dbus;
reg [7:0] sbus;
// ALU Signals
reg [7:0] alua;
reg [7:0] alub;
wire [7:0] aluout;
wire alucout;
wire aluz;
// ALU A and B mux selects.
parameter [1:0] ALUASEL_W = 2'b00,
ALUASEL_SBUS = 2'b01,
ALUASEL_K = 2'b10,
ALUASEL_BD = 2'b11;
parameter [1:0] ALUBSEL_W = 2'b00,
ALUBSEL_SBUS = 2'b01,
ALUBSEL_K = 2'b10,
ALUBSEL_1 = 2'b11;
// ALU Operation codes.
parameter [3:0] ALUOP_ADD = 4'b0000;
parameter [3:0] ALUOP_SUB = 4'b1000;
parameter [3:0] ALUOP_AND = 4'b0001;
parameter [3:0] ALUOP_OR = 4'b0010;
parameter [3:0] ALUOP_XOR = 4'b0011;
parameter [3:0] ALUOP_COM = 4'b0100;
parameter [3:0] ALUOP_ROR = 4'b0101;
parameter [3:0] ALUOP_ROL = 4'b0110;
parameter [3:0] ALUOP_SWAP = 4'b0111;
// Instantiate
regs regs (
.clk (clk),
.reset (reset),
.we (regfilewe),
.re (regfilere),
.bank (fileaddr[6:5]),
.location (fileaddr[4:0]),
.din (regfilein),
.dout (regfileout)
);
// Instatiate the ALU.
alu alu (
.op (aluop),
.a (alua),
.b (alub),
.y (aluout),
.cin (status[0]),
.cout (alucout),
.zout (aluz)
);
wire idecwwe;
wire idecfwe;
wire ideczwe;
wire ideccwe;
idec idec (
.inst (inst),
.aluasel (aluasel),
.alubsel (alubsel),
.aluop (aluop),
.wwe (idecwwe),
.fwe (idecfwe),
.zwe (ideczwe),
.cwe (ideccwe),
.bdpol (bdpol),
.option (isoption),
.tris (istris)
);
assign wwe = idecwwe;
assign fwe = idecfwe;
assign zwe = ideczwe;
assign cwe = ideccwe;
assign debugw = w;
assign debugpc = pc;
assign debuginst = inst;
assign debugstatus = status;
// REGISTER FILE Address
always @(fsel or fsr or status) begin
if (fsel == INDF_ADDRESS) begin
fileaddr = fsr[6:0];
end
else begin
fileaddr = {status[6:5], fsel};
end
end
always @(regfilesel or fwe)
regfilewe = regfilesel & fwe;
always @(regfilesel or aluasel or alubsel)
regfilere = regfilesel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));
// Address Decodes
always @(fileaddr) begin
casex (fileaddr)
7'bXX00XXX:
begin
specialsel = 1'b1;
regfilesel = 1'b0;
expsel = 1'b0;
end
7'b11111XX:
begin
specialsel = 1'b0;
regfilesel = 1'b0;
expsel = 1'b1;
end
default:
begin
specialsel = 1'b0;
regfilesel = 1'b1;
expsel = 1'b0;
end
endcase
end
// Expansion Interface
always @(dbus)
expdout = dbus;
always @(fileaddr)
expaddr = fileaddr;
always @(expsel or aluasel or alubsel)
expread = expsel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));
always @(expsel or fwe)
expwrite = expsel & fwe;
// SBUS
always @(fsel or fsr or tmr0 or pc or status
or porta or portb or portc or regfileout or expdin
or specialsel or regfilesel or expsel) begin
if (specialsel) begin
case (fsel[2:0])
3'h0: sbus = fsr;
3'h1: sbus = tmr0;
3'h2: sbus = pc[7:0];
3'h3: sbus = status;
3'h4: sbus = fsr;
3'h5: sbus = porta;
3'h6: sbus = portb;
3'h7: sbus = portc;
endcase
end
else begin
if (expsel) begin
sbus = expdin;
end
else begin
if (regfilesel) begin
sbus = regfileout;
end
else begin
sbus = 8'h00;
end
end
end
end
// DBUS
always @(aluout)
dbus = aluout;
always @(dbus)
regfilein = dbus;
always @(pc_in)
paddr = pc_in;
assign k = inst[7:0];
assign fsel = inst[4:0];
assign d = inst[5];
assign b = inst[7:5];
// Bit Decoder
always @(b) begin
case (b)
3'b000: bdec = 8'b00000001;
3'b001: bdec = 8'b00000010;
3'b010: bdec = 8'b00000100;
3'b011: bdec = 8'b00001000;
3'b100: bdec = 8'b00010000;
3'b101: bdec = 8'b00100000;
3'b110: bdec = 8'b01000000;
3'b111: bdec = 8'b10000000;
endcase
end
always @(bdec or bdpol)
bd = (bdpol) ? ~bdec : bdec;
always @(posedge clk) begin
if (reset) begin
inst <= 12'h000;
end
else begin
if (skip == 1'b1) begin
inst <= 12'b000000000000;
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -