1.regfile.v
module regfile (rna, rnb, d, wn,we, clk, clrn, qa, qb);
input [4:0] rna,rnb,wn;
input [31:0] d;
input we, clk, clrn;
output [31:0] qa,qb;
reg [31:0] register [1:31]; // 31 x 32-bit regs
// 2 read ports
assign qa = (rna == 0) ? 0 : register[rna];
assign qb = (rnb == 0) ? 0 : register[rnb];
// 1 write port
always @(posedge clk or negedge clrn)
begin
if (clrn==0)
begin
integer i;
for(i=1;i<32;i=i+1)
register[i] <= 0;
end
else if((wn!=0)&&we)
register[wn] <= d;
end
endmodule
2.sccmop_dataflow.v
module sccomp_dataflow(clock, resetn, inst, pc, aluout, memout,mem_clk);
input clock, resetn,mem_clk;
output [31:0] inst,pc, aluout,memout;
wire [31:0] data;
wire wmem;
sccpu_dataflow s (clock, resetn, inst,memout,pc, wmem, aluout, data);
scinstmem imem (pc,inst);
scdatamem dmem (clock, memout, data, aluout, wmem, mem_clk, mem_clk);
endmodule
3.sccpu_dataflow.v
module sccpu_dataflow(clock, resetn, inst,mem,pc, wmem,alu,data);
input [31:0] inst,mem;
input clock,resetn;
output [31:0] pc,alu,data;
output wmem;
wire [31:0] p4 , bpc, npc, adr, ra, alua, alub, res, alu_mem;
wire [3:0] aluc;
wire [4:0] reg_dest, wn;
wire [1:0] pcsource;
wire zero, wmem, wreg, regrt, m2reg, shift, aluimm, jal, sext;
wire [31:0] sa = {27'b0,inst[10:6]};
wire [31:0] offset = {imm[13:0],inst[15:0],2'b00};
sccu_dataflow cu (inst[31:26] , inst[5:0] , zero, wmem,wreg,regrt,m2reg, aluc, shift, aluimm,pcsource, jal, sext);
wire e = sext & inst[15];
wire [15:0] imm = {16{e}};
wire [31:0] immediate = {imm,inst[15:0]};
dff32 ip (npc,clock,resetn,pc);
cla32 pcplus4 (pc,32'h4,1'b0,p4);
cla32 br_adr (p4,offset,1'b0, adr);
wire [31:0] jpc = {p4[31:28],inst[25:0],2'b00};
mux2x32 alu_b (data, immediate,aluimm, alub) ;
mux2x32 alu_a (ra,sa,shift,alua);
mux2x32 result (alu,mem,m2reg,alu_mem);
mux2x32 link (alu_mem,p4,jal,res);
mux2x5 reg_wn (inst[15:11], inst[20: 16] , regrt, reg_dest);
assign wn = reg_dest | {5{jal}}; //ja1: r31 <-- p4;
mux4x32 nextpc (p4,adr,ra, jpc,pcsource,npc);
regfile rf (inst[25:21] ,inst[20:16] ,res,wn,wreg,clock,resetn,ra,data);
alu al_unit (alua,alub,aluc,alu, zero);
endmodule
4.sccu_dataflow.v
module sccu_dataflow (op,func,z,wmem,wreg,regrt,m2reg,aluc,shift,aluimm,pcsource,jal,sext);
input [5:0] op,func;
input z;
output wreg,regrt,jal,m2reg,shift,aluimm,sext,wmem;
output [3:0] aluc;
output [1:0] pcsource;
wire r_type = ~|op;
wire i_add = r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_sub = r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_and = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
wire i_or = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&func[0];
wire i_xor = r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
wire i_sll = r_type&~func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_srl = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_sra = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
wire i_jr = r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
wire i_addi = ~op[5]&~op[4]&op[3]&~op[2]&~op[1]&~op[0];
wire i_andi = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&~op[0];
wire i_ori = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
wire i_xori = ~op[5]&~op[4]&op[3]&op[2]&op[1]&~op[0];
wire i_lw = op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
wire i_sw = op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
wire i_beq = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
wire i_bne = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&op[0];
wire i_lui = ~op[5]&~op[4]&op[3]&op[2]&op[1]&op[0];
wire i_j = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
wire i_jal = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
assign wreg = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_jal;
assign regrt= i_addi|i_andi|i_ori|i_xori|i_lw|i_lui;
assign jal= i_jal;
assign m2reg= i_lw;
assign shift=i_sll|i_srl|i_sra;
assign aluimm=i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_sw;
assign sext =i_addi|i_lw|i_sw|i_beq|i_bne;
assign aluc[3]=i_sra;
assign aluc[2]=i_sub|i_or|i_srl|i_sra|i_ori|i_lui;
assign aluc[1]=i_xor|i_sll|i_sra|i_xori|i_beq|i_bne|i_lui;
assign aluc[0]=i_and|i_or|i_sll|i_srl|i_sra|i_andi|i_ori;
assign wmem = i_sw;
assign pcsource[1]=i_jr|i_j|i_jal;
assign pcsource[0]=i_beq&z|i_bne&~z|i_j|i_jal;
endmodule
5.scdatamem.v
/*module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input [31:0] datain;
input [31:0] addr ;
input clk, we, inclk, outclk;
output [31:0] dataout;
wire write_enable = we & ~clk;
lpm_ram_dp ram(.data(datain),
.address (addr[6:2]),
.we(write_enable),
.outclock(outclk),
.q(dataout));
defparam ram.lpm_width = 32;
defparam ram.lpm_widthad = 5;
defparam ram.lpm_indata = "registered";
defparam ram.lpm_outdata = "registered";
defparam ram.lpm_file = "scdatamem.mif";
defparam ram.lpm_address_control = "registered";
//defparam ram.lpm_rdaddress_control = "registered";
//defparam ram.lpm_wraddress_control = "registered";
endmodule*/
module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input [31:0] datain;
input [31:0] addr ;
input clk, we, inclk, outclk;
output [31:0] dataout;
reg [31:0] ram [0:31];
assign dataout =ram[addr[6:2]];
always @ (posedge clk) begin
if (we) ram[addr[6:2]] = datain;
end
integer i;
initial begin
for (i = 0;i < 32;i = i + 1)
ram[i] = 0;
ram[5'h14] = 32'h000000a3;
ram[5'h15] = 32'h00000027;
ram[5'h16] = 32'h00000079;
ram[5'h17] = 32'h00000115;
end
endmodule
6.scinstmem.v
/*module scinstmem (a,inst);
input [31:0] a;
output [31:0] inst;
lpm_rom lpm_rom_component (.address (a[6:2]),
.q (inst));
defparam lpm_rom_component.lpm_width = 32,
lpm_rom_component.lpm_widthad = 5,
lpm_rom_component.lpm_numwords = "unused",
lpm_rom_component.lpm_file = "scinstmem.mif",
lpm_rom_component.lpm_indata = "unused",
lpm_rom_component.lpm_outdata = "unregistered",
lpm_rom_component.lpm_address_control ="unregistered";
endmodule*/
module scinstmem (a,inst);
input [31:0] a;
output [31:0] inst;
wire [31:0] rom [0:31];
assign rom[5'h00] = 32'h3c010000; // (00) main: lui r1,0
assign rom[5'h01] = 32'h34240050; // (04) ori r4,r1,80
assign rom[5'h02] = 32'h20050004; // (08) addi r5,r0, 4
assign rom[5'h03] = 32'h0c000018; // (0c)call: jal sum
assign rom[5'h04] = 32'hac820000; // (10) sw r2,0(r4)
assign rom[5'h05] = 32'h8c890000; // (14) lw r9, 0(r4)
assign rom[5'h06] = 32'h01244022; // (18) sub r8, r9. r4
assign rom[5'h07] = 32'h20050003; // (lc) addi r5, r0. 3
assign rom[5'h08] = 32'h20a5ffff; // (20) loop2: addi r5, r5, -1
assign rom[5'h09] = 32'h34a8ffff; // (24) ori r8, r5, 0xffff
assign rom[5'h0A] = 32'h39085555; // (28) xori r8. r8, 0x5555
assign rom[5'h0B] = 32'h2009ffff; // (2c) addi r9, rO, -1
assign rom[5'h0C] = 32'h312affff; // (30) andi rlO, r9, 0xffff
assign rom[5'h0D] = 32'h01493025; // (34) or r6. rlO, r9
assign rom[5'h0E] = 32'h01494026; // (38) xor r8, rlO, r9
assign rom[5'h0F] = 32'h01463824; // (3c) and r7, rlO, r6
assign rom[5'h10] = 32'h10a00001; // (40) beq r5, r0, shift
assign rom[5'h11] = 32'h08000008; // (44) j loop2
assign rom[5'h12] = 32'h2005ffff; // (48) shift: addi r5. r0, -1
assign rom[5'h13] = 32'h000543c0; // (4c) sll r8. r5. 15
assign rom[5'h14] = 32'h00084400; // (50) sll r8, r8, 16
assign rom[5'h15] = 32'h00084403; // (54) sra r8, r8, 16
assign rom[5'h16] = 32'h000843c2; // (58) srl r8. r8. 15
assign rom[5'h17] = 32'h08000017; // (5c) finish: j finish
assign rom[5'h18] = 32'h00004020; // (60) sum: add r8, r0, r0
assign rom[5'h19] = 32'h8c890000; // (64) loop: lw r9, (r4)
assign rom[5'h1A] = 32'h20840004; // (68) addi r4, r4, 4
assign rom[5'h1B] = 32'h01094020; // (6c) add r8, r8, r9
assign rom[5'h1C] = 32'h20a5ffff; // (70) addi r5, r5, -1
assign rom[5'h1D] = 32'h14a0fffb; // (74) bne rS, r0, loop
assign rom[5'h1E] = 32'h00081000; // (78) sll r2f r8f 0
assign rom[5'h1F] = 32'h03e00008; // (7c) jr r31
assign inst = rom[a[6:2]];
endmodule
7.shift.v
module shift (d,sa,right,arith,sh);
input [31:0] d;
input [4:0] sa;
input right,arith;
output [31:0] sh;
reg [31:0] sh;
always @* begin
if (!right) begin //shift left
sh = d << sa;
end else if (!arith) begin //shift right logical
sh = d >> sa;
end else begin //shift right arithmetic
sh = $signed(d) >>> sa;
end
end
endmodule