0];
wire[31:
0]word;
initial
begin
$readmemh("memfile.dat",RAM);
end
//readandwritebytesfrom32-bitword
always@(posedgeclk)
if(memwrite)
case(adr[1:
0])
2'b00:
RAM[adr>>2][7:
0]<=writedata;
2'b01:
RAM[adr>>2][15:
8]<=writedata;
2'b10:
RAM[adr>>2][23:
16]<=writedata;
2'b11:
RAM[adr>>2][31:
24]<=writedata;
endcase
assignword=RAM[adr>>2];
always@(*)
case(adr[1:
0])
2'b00:
memdata<=word[31:
24];
2'b01:
memdata<=word[23:
16];
2'b10:
memdata<=word[15:
8];
2'b11:
memdata<=word[7:
0];
endcase
endmodule
//simplifiedMIPSprocessor
modulemips#(parameterWIDTH=8,REGBITS=3)
(inputclk,reset,
input[WIDTH-1:
0]memdata,
outputmemread,memwrite,
output[WIDTH-1:
0]adr,writedata);
wire[31:
0]instr;
wirezero,alusrca,memtoreg,iord,pcen,regwrite,regdst;
wire[1:
0]aluop,pcsource,alusrcb;
wire[3:
0]irwrite;
wire[2:
0]alucont;
controllercont(clk,reset,instr[31:
26],zero,memread,memwrite,
alusrca,memtoreg,iord,pcen,regwrite,regdst,
pcsource,alusrcb,aluop,irwrite);
alucontrolac(aluop,instr[5:
0],alucont);
datapath#(WIDTH,REGBITS)
dp(clk,reset,memdata,alusrca,memtoreg,iord,pcen,
regwrite,regdst,pcsource,alusrcb,irwrite,alucont,
zero,instr,adr,writedata);
endmodule
modulecontroller(inputclk,reset,
input[5:
0]op,
inputzero,
outputregmemread,memwrite,alusrca,memtoreg,iord,
outputpcen,
outputregregwrite,regdst,
outputreg[1:
0]pcsource,alusrcb,aluop,
outputreg[3:
0]irwrite);
parameterFETCH1=4'b0001;
parameterFETCH2=4'b0010;
parameterFETCH3=4'b0011;
parameterFETCH4=4'b0100;
parameterDECODE=4'b0101;
parameterMEMADR=4'b0110;
parameterLBRD=4'b0111;
parameterLBWR=4'b1000;
parameterSBWR=4'b1001;
parameterRTYPEEX=4'b1010;
parameterRTYPEWR=4'b1011;
parameterBEQEX=4'b1100;
parameterJEX=4'b1101;
parameterLB=6'b100000;
parameterSB=6'b101000;
parameterRTYPE=6'b0;
parameterBEQ=6'b000100;
parameterJ=6'b000010;
reg[3:
0]state,nextstate;
regpcwrite,pcwritecond;
//stateregister
always@(posedgeclk)
if(reset)state<=FETCH1;
elsestate<=nextstate;
//nextstatelogic
always@(*)
begin
case(state)
FETCH1:
nextstate<=FETCH2;
FETCH2:
nextstate<=FETCH3;
FETCH3:
nextstate<=FETCH4;
FETCH4:
nextstate<=DECODE;
DECODE:
case(op)
LB:
nextstate<=MEMADR;
SB:
nextstate<=MEMADR;
RTYPE:
nextstate<=RTYPEEX;
BEQ:
nextstate<=BEQEX;
J:
nextstate<=JEX;
default:
nextstate<=FETCH1;//shouldneverhappen
endcase
MEMADR:
case(op)
LB:
nextstate<=LBRD;
SB:
nextstate<=SBWR;
default:
nextstate<=FETCH1;//shouldneverhappen
endcase
LBRD:
nextstate<=LBWR;
LBWR:
nextstate<=FETCH1;
SBWR:
nextstate<=FETCH1;
RTYPEEX:
nextstate<=RTYPEWR;
RTYPEWR:
nextstate<=FETCH1;
BEQEX:
nextstate<=FETCH1;
JEX:
nextstate<=FETCH1;
default:
nextstate<=FETCH1;//shouldneverhappen
endcase
end
always@(*)
begin
//setalloutputstozero,thenconditionallyassertjusttheappropriateones
irwrite<=4'b0000;
pcwrite<=0;pcwritecond<=0;
regwrite<=0;regdst<=0;
memread<=0;memwrite<=0;
alusrca<=0;alusrcb<=2'b00;aluop<=2'b00;
pcsource<=2'b00;
iord<=0;memtoreg<=0;
case(state)
FETCH1:
begin
memread<=1;
irwrite<=4'b1000;
alusrcb<=2'b01;
pcwrite<=1;
end
FETCH2:
begin
memread<=1;
irwrite<=4'b0100;
alusrcb<=2'b01;
pcwrite<=1;
end
FETCH3:
begin
memread<=1;
irwrite<=4'b0010;
alusrcb<=2'b01;
pcwrite<=1;
end
FETCH4:
begin
memread<=1;
irwrite<=4'b0001;
alusrcb<=2'b01;
pcwrite<=1;
end
DECODE:
alusrcb<=2'b11;
MEMADR:
begin
alusrca<=1;
alusrcb<=2'b10;
end
LBRD:
begin
memread<=1;
iord<=1;
end
LBWR:
begin
regwrite<=1;
memtoreg<=1;
end
SBWR:
begin
memwrite<=1;
iord<=1;
end
RTYPEEX:
begin
alusrca<=1;
aluop<=2'b10;
end
RTYPEWR:
begin
regdst<=1;
regwrite<=1;
end
BEQEX:
begin
alusrca<=1;
aluop<=2'b01;
pcwritecond<=1;
pcsource<=2'b01;
end
JEX:
begin
pcwrite<=1;
pcsource<=2'b10;
end
endcase
end
assignpcen=pcwrite|(pcwritecond&zero);//programcounterenable
endmodule
modulealucontrol(input[1:
0]aluop,
input[5:
0]funct,
outputreg[2:
0]alucont);
always@(*)
case(aluop)
2'b00:
alucont<=3'b010;//addforlb/sb/addi
2'b01:
alucont<=3'b110;//sub(forbeq)
default:
case(funct)//R-Typeinstructions
6'b100000:
alucont<=3'b010;//add(foradd)
6'b100010:
alucont<=3'b110;//subtract(forsub)
6'b100100:
alucont<=3'b000;//logicaland(forand)
6'b100101:
alucont<=3'b001;//logicalor(foror)
6'b101010:
alucont<=3'b111;//setonless(forslt)
default:
alucont<=3'b101;//shouldneverhappen
endcase
endcase
endmodule
moduledatapath#(parameterWIDTH=8,REGBITS=3)
(inputclk,reset,
input[WIDTH-1:
0]memdata,
inputalusrca,memtoreg,iord,pcen,regwrite,regdst,
input[1:
0]pcsource,alusrcb,
input[3:
0]irwrite,
input[2:
0]alucont,
outputzero,
output[31:
0]instr,
output[WIDTH-1:
0]adr,writedata);
//thesizeoftheparametersmustbechangedtomatchtheWIDTHparameter
parameterCONST_ZERO=8'b0;
parameterCONST_ONE=8'b1;
wire[REGBITS-1:
0]ra1,ra2,wa;
wire[WIDTH-1:
0]pc,nextpc,md,rd1,rd2,wd,a,src1,src2,aluresult,
aluout,constx4;
//shiftleftconstantfieldby2
assignconstx4={instr[WIDTH-3:
0],2'b00};
//registerfileaddressfields
assignra1=instr[REGBITS+20:
21];
assignra2=instr[REGBITS+15:
16];
mux2#(REGBITS)regmux(instr[REGBITS+15:
16],instr[REGBITS+10:
11],regdst,wa);
//independentofbitwidth,loadinstructionintofour8-bitregistersoverfourcycles
flopen#(8)ir0(clk,irwrite[0],memdata[7:
0],instr[7:
0]);
flopen#(8)ir1(clk,irwrite[1],memdata[7:
0],instr[15:
8]);
flopen#(8)ir2(clk,irwrite[2],memdata[7:
0],instr[23:
16]);
flopen#(8)ir3(clk,irwrite[3],memdata[7:
0],instr[31:
24]);
//datapath
flopenr#(WIDTH)pcreg(clk,reset,pcen,nextpc,pc);
flop#(WIDTH)mdr(clk,memdata,md);
flop#(WIDTH)areg(clk,rd1,a);
flop#(WIDTH)wrd(clk,rd2,writedata);
flop#(WIDTH)res(clk,aluresult,aluout);
mux2#(WIDTH)adrmux(pc,aluout,iord,adr);
mux2#(WIDTH)src1mux(pc,a,alusrca,src1);
mux4#(WIDTH)src2mux(writedata,CONST_ONE,instr[WIDTH-1:
0],
constx4,alusrcb,src2);
mux4#(WIDTH)pcmux(aluresult,aluout,constx4,CONST_ZERO,pcsource,nextpc);
mux2#(WIDTH)wdmux(aluout,md,memtoreg,wd);
regfile#(WIDTH,REGBITS)rf(clk,regwrite,ra1,ra2,wa,wd,rd1,rd2);
alu#(WIDTH)alunit(src1,src2,alucont,aluresult);
zerodetect#(WIDTH)zd(aluresult,zero);
endmodule
modulealu#(parameterWIDTH=8)
(input[WIDTH-1:
0]a,b,
input[2:
0]alucont,
outputreg[WIDTH-1:
0]result);
wire[WIDTH-1:
0]b2,sum,slt;
assignb2=alucont[2]?
~b:
b;
assignsum=a+b2+alucont[2];
//sltshouldbe1ifmostsignificantbitofsumis1
assignslt=sum[WIDTH-1];
always@(*)
case(alucont[1:
0])
2'b00:
result<=a&b;
2'b01:
result<=a|b;
2'b10:
result<=sum;
2'b11:
result<=slt;
endcase
endmodule
moduleregfile#(parameterWIDTH=8,REGBITS=3)
(inputclk,
inputregwrite,
input[REGBITS-1:
0]ra1,ra2,wa,
input[WIDTH-1:
0]wd,
output[WIDTH-1:
0]rd1,rd2);
reg[WIDTH-1:
0]RAM[(1<0];
//threeportedregisterfile
//readtwoportscombinationally
//writethirdportonrisingedgeofclock
//register0hardwiredto0
always@(posedgeclk)
if(regwrite)RAM[wa]<=wd;
assignrd1=ra1?
RAM[ra1]:
0;
assignrd2=ra2?
RAM[ra2]:
0;
endmodule
modulezerodetect#(parameterWIDTH=8)
(input[WIDTH-1:
0]a,
outputy);
assigny=(a==0);
endmodule
moduleflop#(parameterWIDTH=8)
(inputclk,
input[WIDTH-1:
0]d,
outputreg[WIDTH-1:
0]q);
always@(posedgeclk)
q<=d;
endmodule
moduleflopen#(parameterWIDTH=8)
(inputclk,en,
input[WIDTH-1:
0]d,
outputreg[WIDTH-1:
0]q);
always@(posedgeclk)
if(en)q<=d;
endmodule
moduleflopenr#(parameterWIDTH=8)
(inputclk,reset,en,
input[WIDTH-1:
0]d,
outputreg[WIDTH-1:
0]q);
always@(posedgeclk)
if(reset)q<=0;
elseif(en)q<=d;
endmodule
modulemux2#(parameterWIDTH=8)
(input[WIDTH-1:
0]d0,d1,
inputs,
output[WIDTH-1:
0]y);
assigny=s?
d1:
d0;
endmodule
modulemux4#(parameterWIDTH=8)