Verilog Single Cycle Datapath Adding Instructions Below is
Verilog - Single Cycle Datapath - Adding Instructions:
Below is a MIPS Single Cycle Datapath:
module top (input clk, reset,output [31:0] writedata, dataadr,output memwrite);
wire [31:0] pc, instr, readdata;
// instantiate processor and memories
mips mips (clk, reset, pc, instr, memwrite, dataadr,
writedata, readdata);
imem imem (pc[7:2], instr);
dmem dmem (clk, memwrite, dataadr, writedata,readdata);
endmodule
module adder (input [31:0] a, b, output [31:0] y);
assign y = a + b;
endmodule
module alu (a,b,sel, out, zero);
input [31:0] a,b;
input [2:0] sel;
output reg [31:0] out;
output reg zero;
initial
begin
out = 0;
zero =1\'b0;
end
always @ (*)
begin
case(sel)
3\'b000:
begin
out=a & b;
if (out == 0)
zero = 1;
else
zero = 0;
end
3\'b001:
begin
out= a | b;
if (out == 0)
zero = 1;
else
zero = 0;
end
3\'b110:
begin
out=a-b;
if (out == 0)
zero = 1;
else
zero = 0;
end
3\'b010:
begin
out=a+b;
if (out == 0)
zero = 1;
else
zero = 0;
end
3\'b111:
begin
if ( a < b)
out = 1;
else
out=0;
end
endcase
end
endmodule
module aludec (input [5:0] funct,
input [1:0] aluop,
output reg [2:0] alucontrol);
always @ (*)
case (aluop)
2\'b00: alucontrol <= 3\'b010; // add
2\'b01: alucontrol <= 3\'b110; // sub
default: case(funct) // RTYPE
6\'b100000: alucontrol <= 3\'b010; // ADD
6\'b100010: alucontrol <= 3\'b110; // SUB
6\'b100100: alucontrol <= 3\'b000; // AND
6\'b100101: alucontrol <= 3\'b001; // OR
6\'b101010: alucontrol <= 3\'b111; // SLT
default: alucontrol <= 3\'bxxx; // ???
endcase
endcase
endmodule
module controller (input [5:0] op, funct,
input zero,
output memtoreg, memwrite,
output pcsrc, alusrc,
output regdst, regwrite,
output jump,
output [2:0] alucontrol);
wire [1:0] aluop;
wire branch;
maindec md(op, memtoreg, memwrite, branch,
alusrc, regdst, regwrite, jump,
aluop);
aludec ad (funct, aluop, alucontrol);
assign pcsrc = branch & zero;
endmodule
module datapath (input clk, reset,
input memtoreg, pcsrc,
input alusrc, regdst,
input regwrite, jump,
input [2:0] alucontrol,
output zero,
output [31:0] pc,
input [31:0] instr,
output [31:0] aluout, writedata,
input [31:0] readdata);
wire [4:0] writereg;
wire [31:0] pcnext, pcnextbr, pcplus4, pcbranch;
wire [31:0] signimm, signimmsh;
wire [31:0] srca, srcb;
wire [31:0] result;
// next PC logic
flopr #(32) pcreg(clk, reset, pcnext, pc);
adder pcadd1 (pc, 32\'b100, pcplus4);
sl2 immsh(signimm, signimmsh);
adder pcadd2(pcplus4, signimmsh, pcbranch);
mux2 #(32) pcbrmux(pcplus4, pcbranch, pcsrc, pcnextbr);
mux2 #(32) pcmux(pcnextbr, {pcplus4[31:28], instr[25:0], 2\'b00},jump, pcnext);
// register file logic
regfile rf(clk, regwrite, instr[25:21],
instr[20:16], writereg, result, srca, writedata);
mux2 #(5) wrmux(instr[20:16], instr[15:11],regdst, writereg);
mux2 #(32) resmux(aluout, readdata, memtoreg, result);
signext se(instr[15:0], signimm);
// ALU logic
mux2 #(32) srcbmux(writedata, signimm, alusrc, srcb);
alu alu(srca, srcb, alucontrol, aluout, zero);
endmodule
module dmem (input clk, we,
input [31:0] a, wd,
output [31:0] rd);
reg [31:0] RAM[63:0];
assign rd = RAM[a[31:2]]; // word aligned
always @ (posedge clk)
if (we)
RAM[a[31:2]] <= wd;
endmodule
module flopr # (parameter WIDTH = 8)
(input clk, reset,
input [WIDTH-1:0] d,
output reg [WIDTH-1:0] q);
always @ (posedge clk, posedge reset)
if (reset) q <= 0;
else q <= d;
endmodule
module imem (input [5:0] a, output [31:0] rd);
reg [31:0] RAM[63:0]; // limited memory
initial
begin
$readmemh (\"memfile.dat\",RAM);
end
assign rd = RAM[a]; // word aligned
endmodule
module maindec (input [5:0] op, output memtoreg, memwrite, output branch, alusrc,
output regdst, regwrite, output jump, output [1:0] aluop);
reg [8:0] controls;
assign {regwrite, regdst, alusrc, branch, memwrite, memtoreg, jump, aluop} = controls;
always @ (* )
case(op)
6\'b000000 : controls <= 9\'b110000010; //Rtyp
6\'b100011 : controls <= 9\'b101001000; //LW
6\'b101011 : controls <= 9\'b001010000; //SW
6\'b000100 : controls <= 9\'b000100001; //BEQ
6\'b001000 : controls <= 9\'b101000000; //ADDI
6\'b000010 : controls <= 9\'b000000100; //J
default: controls <= 9\'bXXXXXXXXX; //???
endcase
endmodule
module mips (input clk, reset,
output [31:0] pc,
input [31:0] instr,
output memwrite,
output [31:0] aluout, writedata,
input [31:0] readdata);
wire memtoreg, branch, alusrc, regdst, regwrite, jump;
wire [2:0] alucontrol;
controller c(instr[31:26], instr[5:0], zero,memtoreg, memwrite, pcsrc,
alusrc, regdst, regwrite, jump, alucontrol);
datapath dp(clk, reset, memtoreg, pcsrc,
alusrc, regdst, regwrite, jump,
alucontrol,
zero, pc, instr,
aluout, writedata, readdata);
endmodule
module mux2 # (parameter WIDTH = 8)
(input [WIDTH-1:0] d0, d1, input s,
output [WIDTH-1:0] y);
assign y = s ? d1 : d0;
endmodule
module regfile (input clk, input we3,
input [4:0] ra1, ra2, wa3,
input [31:0] wd3,
output [31:0] rd1, rd2);
reg [31:0] rf[31:0];
// three ported register file
// read two ports combinationally
// write third port on rising edge of clock
// register 0 hardwired to 0
always @ (posedge clk)
if (we3) rf[wa3] <= wd3;
assign rd1 = (ra1 != 0) ? rf[ra1] : 0;
assign rd2 = (ra2 != 0) ? rf[ra2] : 0;
endmodule
module signext (input [15:0] a,
output [31:0] y);
assign y = {{16{a[15]}}, a};
endmodule
module sl2 (input [31:0] a, output [31:0] y);
// shift left by 2
assign y = {a[25:0], 2\'b00};
endmodule
module testbench();
reg clk;
reg reset;
wire [31:0] writedata, dataadr;
wire memwrite;
// instantiate device to be tested
top dut (clk, reset, writedata, dataadr, memwrite);
// initialize test
initial
begin
reset <= 1; # 22; reset <= 0;
end
// generate clock to sequence tests
always
begin
clk <= 1;
# 5;
clk <= 0;
# 5; // clock duration
end
// check results
always @ (negedge clk)
begin
if (memwrite) begin
if (dataadr === 84 & writedata === 7) begin
$display (\"Simulation succeeded\");
$stop;
end else if (dataadr !== 80) begin
$display (\"Simulation failed\");
$stop;
end
end
end
endmodule
Modify the code and extend the instruction set of the functional unit with operations
SLL, SRL, SLLV, and SRLV.
Solution
module srle_example (clk, enable, data_in, result);
parameter cycle=4;
parameter width = 31;
input clk, enable;
input [0:width] data_in;
output [0:width] result;
reg [0:width-1] shift [cycle-1:0];
integer i;
always @(posedge clk)
begin
if (enable == 1) begin
for (i = (cycle-1);i >0; i=i-1) shift[i] = shift[i-1];
shift[0] = data_in;
end
end
assign result = shift[cycle-1];
endmodule
case(opcode1)
\'SLL: result=s2_contents<<sa;
\'SLLV: result=s2_contents<<s1_contents;
\'SRL: result=s2_contents>>sa;
\'SRLV:result=s2_contents>>s1_contents;
begin
result=s2_contents;
for(j=0;j<sa;j=j+1)
begin
result=result>>1;
result={s2_contents[33],result[31:0]};
end
end
begin
result=s2_contents;
for(j=0;j<s1_contents;j=j+1)
begin
result=result>>1;
result={s2_contents[33],result[31:0]};
end
end
Endmodule
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-0.webp)
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-1.webp)
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-2.webp)
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-3.webp)
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-4.webp)
![Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp Verilog - Single Cycle Datapath - Adding Instructions: Below is a MIPS Single Cycle Datapath: module top (input clk, reset,output [31:0] writedata, dataadr,outp](/WebImages/13/verilog-single-cycle-datapath-adding-instructions-below-is-1014478-1761524010-5.webp)