diff options
Diffstat (limited to '')
| -rw-r--r-- | ee4363/mp1/MIPSALU.v | 18 | ||||
| -rw-r--r-- | ee4363/mp1/MIPSAlu.vcd | 57 | ||||
| -rw-r--r-- | ee4363/mp1/mipspipe.v | 90 | ||||
| -rw-r--r-- | ee4363/mp1/out | 152 | ||||
| -rw-r--r-- | ee4363/mp1/test_mipsalu.v | 49 | ||||
| -rw-r--r-- | ee4363/mp1/test_mipspipe.v | 53 | 
6 files changed, 419 insertions, 0 deletions
diff --git a/ee4363/mp1/MIPSALU.v b/ee4363/mp1/MIPSALU.v new file mode 100644 index 0000000..096aff5 --- /dev/null +++ b/ee4363/mp1/MIPSALU.v @@ -0,0 +1,18 @@ +module MIPSALU (ALUctl, A, B, ALUOut, Zero); +  input [3:0] ALUctl; +  input [31:0] A,B; +  output reg [31:0] ALUOut; +  output Zero; +  assign Zero = (ALUOut==0);  +  always @(ALUctl, A, B) +      case (ALUctl) +         0: ALUOut <= A & B; +         1: ALUOut <= A | B; +         2: ALUOut <= A + B; +         6: ALUOut <= A - B; +         7: ALUOut <= A < B ? 1:0; +         12: ALUOut <= ~(A | B);           +		 default: ALUOut <= 0;  +      endcase +endmodule + diff --git a/ee4363/mp1/MIPSAlu.vcd b/ee4363/mp1/MIPSAlu.vcd new file mode 100644 index 0000000..e20e5e6 --- /dev/null +++ b/ee4363/mp1/MIPSAlu.vcd @@ -0,0 +1,57 @@ +$date +	Sat Nov 21 15:12:24 2020 +$end +$version +	Icarus Verilog +$end +$timescale +	100ps +$end +$scope module test_mipsalu $end +$var wire 1 ! Zero $end +$var wire 32 " ALUOut [31:0] $end +$var reg 32 # A [31:0] $end +$var reg 4 $ ALUctl [3:0] $end +$var reg 32 % B [31:0] $end +$scope module U0 $end +$var wire 32 & A [31:0] $end +$var wire 4 ' ALUctl [3:0] $end +$var wire 32 ( B [31:0] $end +$var wire 1 ! Zero $end +$var reg 32 ) ALUOut [31:0] $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +$dumpvars +b0 ) +b1010101010101010101010101010101 ( +bx ' +b1010101010101010101010101010101 & +b1010101010101010101010101010101 % +bx $ +b1010101010101010101010101010101 # +b0 " +1! +$end +#100 +0! +b1010101010101010101010101010101 " +b1010101010101010101010101010101 ) +b0 $ +b0 ' +#200 +b1 $ +b1 ' +#300 +b10101010101010101010101010101010 " +b10101010101010101010101010101010 ) +b10 $ +b10 ' +#400 +1! +b0 " +b0 ) +b110 $ +b110 ' +#500 diff --git a/ee4363/mp1/mipspipe.v b/ee4363/mp1/mipspipe.v new file mode 100644 index 0000000..951bde0 --- /dev/null +++ b/ee4363/mp1/mipspipe.v @@ -0,0 +1,90 @@ +// Incomplete behavioral model of MIPS pipeline + +module mipspipe(clock); +   // in_out +   input clock; + +   // Instruction opcodes +   parameter LW = 6'b100011, SW = 6'b101011, BEQ = 6'b000100, nop = 32'b00000_100000, ALUop = 6'b0;  +   reg [31:0] PC, // Program counter +		  Regs[0:31],  // Register file +			  IMemory[0:1023], DMemory[0:1023], // Instruction and data memories +              IFIDIR, IDEXA, IDEXB, IDEXIR, EXMEMIR, EXMEMB, // pipeline latches +              EXMEMALUOut, MEMWBValue, MEMWBIR; // pipeline latches + +   wire [4:0] IDEXrs, IDEXrt, EXMEMrd, MEMWBrd, MEMWBrt; // fields of pipeline latches +   wire [5:0] EXMEMop, MEMWBop, IDEXop; // opcodes +   wire [31:0] Ain, Bin; // ALU inputs + +   // Define fields of pipeline latches +   assign IDEXrs = IDEXIR[25:21]; // rs field +   assign IDEXrt = IDEXIR[20:16]; // rt field +   assign EXMEMrd = EXMEMIR[15:11]; // rd field +   assign MEMWBrd = MEMWBIR[15:11]; // rd field +   assign MEMWBrt = MEMWBIR[20:16]; // rt field -- for loads +   assign EXMEMop = EXMEMIR[31:26]; // opcode +   assign MEMWBop = MEMWBIR[31:26]; // opcode +   assign IDEXop = IDEXIR[31:26]; // opcode + +   // Inputs to the ALU come directly from the ID/EX pipeline latches +   assign Ain = IDEXA; +   assign Bin = IDEXB; +   reg [5:0] i; //used to initialize registers +   reg [10:0] j,k; //used to initialize registers + +   initial begin +      PC = 0; +      IFIDIR = nop;  +      IDEXIR = nop;  +      EXMEMIR = nop;  +      MEMWBIR = nop; // no-ops placed in pipeline latches +      // test some instructions +      for (i=0;i<=31;i=i+1) Regs[i] = i; // initialize registers +      IMemory[0] = 32'h8c210003; +      IMemory[1] = 32'hac020000; +      IMemory[2] = 32'h00642820; +      for (j=3;j<=1023;j=j+1) IMemory[j] = nop; +      DMemory[0] = 32'h00000000; +      DMemory[1] = 32'hffffffff; +      for (k=2;k<=1023;k=k+1) DMemory[k] = 0; +   end +    +   always @ (posedge clock)  +   begin +      // FETCH: Fetch instruction & update PC +      IFIDIR <= IMemory[PC>>2]; +	  PC <= PC + 4; +     +      // DECODE: Read registers  +      IDEXA <= Regs[IFIDIR[25:21]];  +      IDEXB <= Regs[IFIDIR[20:16]]; // get two registers +       +	  IDEXIR <= IFIDIR; // pass along IR +       +      // EX: Address calculation or ALU operation +      if ((IDEXop==LW) |(IDEXop==SW)) // address calculation +         EXMEMALUOut <= IDEXA +{{16{IDEXIR[15]}}, IDEXIR[15:0]}; +      else if (IDEXop==ALUop) begin // ALU operation +         case (IDEXIR[5:0]) // R-type instruction +           32: EXMEMALUOut <= Ain + Bin; // add operation +           default: ; // other R-type operations [to be implemented] +         endcase +      end +    +      EXMEMIR <= IDEXIR; EXMEMB <= IDEXB; //pass along the IR & B +    +      // MEM  +      if (EXMEMop==ALUop) MEMWBValue <= EXMEMALUOut; //pass along ALU result +      else if (EXMEMop == LW) MEMWBValue <= DMemory[EXMEMALUOut>>2]; // load +      else if (EXMEMop == SW) DMemory[EXMEMALUOut>>2] <=EXMEMB; // store +    +      MEMWBIR <= EXMEMIR; //pass along IR +    +      // WB  +      if ((MEMWBop==ALUop) & (MEMWBrd != 0)) // update registers if ALU operation and destination not 0 +		Regs[MEMWBrd] <= MEMWBValue; // ALU operation +      else if ((MEMWBop == LW)& (MEMWBrt != 0)) // Update registers if load and destination not 0 +		Regs[MEMWBrt] <= MEMWBValue; +    end + +endmodule diff --git a/ee4363/mp1/out b/ee4363/mp1/out new file mode 100644 index 0000000..b57aa85 --- /dev/null +++ b/ee4363/mp1/out @@ -0,0 +1,152 @@ +#! /usr/bin/vvp +:ivl_version "10.3 (stable)"; +:ivl_delay_selection "TYPICAL"; +:vpi_time_precision - 10; +:vpi_module "system"; +:vpi_module "vhdl_sys"; +:vpi_module "v2005_math"; +:vpi_module "va_math"; +S_0x558b9129cd10 .scope module, "test_mipsalu" "test_mipsalu" 2 8; + .timescale -9 -10; +v0x558b912b2050_0 .var "A", 31 0; +v0x558b912b2130_0 .net "ALUOut", 31 0, v0x558b912b1b10_0;  1 drivers +v0x558b912b2200_0 .var "ALUctl", 3 0; +v0x558b912b2300_0 .var "B", 31 0; +v0x558b912b23d0_0 .net "Zero", 0 0, L_0x558b912c2530;  1 drivers +S_0x558b9129ce90 .scope module, "U0" "MIPSALU" 2 19, 3 1 0, S_0x558b9129cd10; + .timescale -9 -10; +    .port_info 0 /INPUT 4 "ALUctl" +    .port_info 1 /INPUT 32 "A" +    .port_info 2 /INPUT 32 "B" +    .port_info 3 /OUTPUT 32 "ALUOut" +    .port_info 4 /OUTPUT 1 "Zero" +v0x558b91265130_0 .net "A", 31 0, v0x558b912b2050_0;  1 drivers +v0x558b912b1b10_0 .var "ALUOut", 31 0; +v0x558b912b1bf0_0 .net "ALUctl", 3 0, v0x558b912b2200_0;  1 drivers +v0x558b912b1ce0_0 .net "B", 31 0, v0x558b912b2300_0;  1 drivers +v0x558b912b1dc0_0 .net "Zero", 0 0, L_0x558b912c2530;  alias, 1 drivers +L_0x7f2d75820018 .functor BUFT 1, C4<00000000000000000000000000000000>, C4<0>, C4<0>, C4<0>; +v0x558b912b1ed0_0 .net/2u *"_s0", 31 0, L_0x7f2d75820018;  1 drivers +E_0x558b9129a7b0 .event edge, v0x558b912b1ce0_0, v0x558b91265130_0, v0x558b912b1bf0_0; +L_0x558b912c2530 .cmp/eq 32, v0x558b912b1b10_0, L_0x7f2d75820018; +    .scope S_0x558b9129ce90; +T_0 ; +    %wait E_0x558b9129a7b0; +    %load/vec4 v0x558b912b1bf0_0; +    %dup/vec4; +    %pushi/vec4 0, 0, 4; +    %cmp/u; +    %jmp/1 T_0.0, 6; +    %dup/vec4; +    %pushi/vec4 1, 0, 4; +    %cmp/u; +    %jmp/1 T_0.1, 6; +    %dup/vec4; +    %pushi/vec4 2, 0, 4; +    %cmp/u; +    %jmp/1 T_0.2, 6; +    %dup/vec4; +    %pushi/vec4 6, 0, 4; +    %cmp/u; +    %jmp/1 T_0.3, 6; +    %dup/vec4; +    %pushi/vec4 7, 0, 4; +    %cmp/u; +    %jmp/1 T_0.4, 6; +    %dup/vec4; +    %pushi/vec4 12, 0, 4; +    %cmp/u; +    %jmp/1 T_0.5, 6; +    %pushi/vec4 0, 0, 32; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.0 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %and; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.1 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %or; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.2 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %add; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.3 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %sub; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.4 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %cmp/u; +    %flag_mov 8, 5; +    %jmp/0 T_0.8, 8; +    %pushi/vec4 1, 0, 32; +    %jmp/1 T_0.9, 8; +T_0.8 ; End of true expr. +    %pushi/vec4 0, 0, 32; +    %jmp/0 T_0.9, 8; + ; End of false expr. +    %blend; +T_0.9; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.5 ; +    %load/vec4 v0x558b91265130_0; +    %load/vec4 v0x558b912b1ce0_0; +    %or; +    %inv; +    %assign/vec4 v0x558b912b1b10_0, 0; +    %jmp T_0.7; +T_0.7 ; +    %pop/vec4 1; +    %jmp T_0; +    .thread T_0, $push; +    .scope S_0x558b9129cd10; +T_1 ; +    %pushi/vec4 1431655765, 0, 32; +    %store/vec4 v0x558b912b2050_0, 0, 32; +    %pushi/vec4 1431655765, 0, 32; +    %store/vec4 v0x558b912b2300_0, 0, 32; +    %delay 100, 0; +    %pushi/vec4 0, 0, 4; +    %store/vec4 v0x558b912b2200_0, 0, 4; +    %delay 100, 0; +    %pushi/vec4 1, 0, 4; +    %store/vec4 v0x558b912b2200_0, 0, 4; +    %delay 100, 0; +    %pushi/vec4 2, 0, 4; +    %store/vec4 v0x558b912b2200_0, 0, 4; +    %delay 100, 0; +    %pushi/vec4 6, 0, 4; +    %store/vec4 v0x558b912b2200_0, 0, 4; +    %delay 100, 0; +    %vpi_call 2 32 "$finish" {0 0 0}; +    %end; +    .thread T_1; +    .scope S_0x558b9129cd10; +T_2 ; +    %vpi_call 2 38 "$monitor", $time, " A = %h", v0x558b912b2050_0, " B = %h", v0x558b912b2300_0, " ALUOut = %h", v0x558b912b2130_0, " Zero = %b", v0x558b912b23d0_0 {0 0 0}; +    %end; +    .thread T_2; +    .scope S_0x558b9129cd10; +T_3 ; +    %vpi_call 2 43 "$dumpfile", "MIPSAlu.vcd" {0 0 0}; +    %vpi_call 2 44 "$dumpvars" {0 0 0}; +    %end; +    .thread T_3; +# The file index is used to find the file name in the following table. +:file_names 4; +    "N/A"; +    "<interactive>"; +    "test_mipsalu.v"; +    "./MIPSALU.v"; diff --git a/ee4363/mp1/test_mipsalu.v b/ee4363/mp1/test_mipsalu.v new file mode 100644 index 0000000..15cdf60 --- /dev/null +++ b/ee4363/mp1/test_mipsalu.v @@ -0,0 +1,49 @@ +   `timescale 1ns/100ps +// +// Test Bench for the mips alu +// T. Posbergh, 14 October 2012 +// +   `include "MIPSALU.v" +// +module test_mipsalu; +   wire Zero;             // ALU bit output +   wire [31:0] ALUOut;    // ALU word output +   reg  [31:0] A,B;       // ALU word inpus +   reg  [3:0]  ALUctl; + +   reg clock; +   reg reset; + +// instantiate the alu and control + +   MIPSALU U0(ALUctl, A, B, ALUOut, Zero); + +// generate test signals + +   initial  +   begin +      A=32'b0101_0101_0101_0101_0101_0101_0101_0101; +      B=32'b0101_0101_0101_0101_0101_0101_0101_0101; +      #10 ALUctl=4'b0000; +      #10 ALUctl=4'b0001; +      #10 ALUctl=4'b0010; +      #10 ALUctl=4'b0110; +//    $finish(100); +      #10 $finish; +    end + +// output result + +   initial +      $monitor($time, " A = %h",A," B = %h",B," ALUOut = %h",ALUOut," Zero = %b",Zero); + +// the following generates vcd file for GTKwave +   initial +      begin +      $dumpfile("MIPSAlu.vcd"); +      $dumpvars; +   end + +endmodule + + diff --git a/ee4363/mp1/test_mipspipe.v b/ee4363/mp1/test_mipspipe.v new file mode 100644 index 0000000..24576ec --- /dev/null +++ b/ee4363/mp1/test_mipspipe.v @@ -0,0 +1,53 @@ +// +// Test bench for the mipspipe +// Boram Lee +// +   +`include "mipspipe.v" +   +module test_mipspipe; +   +  reg clock; +  reg [3:0] clock_cycle; + +// instantiate pipeline module +  mipspipe u_mipspipe(clock); +  +// initialize clock and cycle counter  +  initial begin +    clock = 0; +    clock_cycle=4'h0; +    #160  $finish; +  end +   +// 10 unit clock cycle +  always  +    #5 clock = ~clock; + +  always @(posedge clock) +     begin +       clock_cycle=clock_cycle+1; +     end + + +// display contents of pipeline latches at the end of each clock cycle +  always @(negedge clock)  +     begin +     $display("\n\nclock cycle = %d",clock_cycle," (time = %1.0t)",$time); +     $display("IF/ID registers\n\t IF/ID.PC+4 = %h, IF/ID.IR = %h \n", u_mipspipe.PC, u_mipspipe.IFIDIR);  +     $display("ID/EX registers\n\t ID/EX.rs = %d, ID/EX.rt = %d",u_mipspipe.IDEXrs,u_mipspipe.IDEXrt,"\n\t ID/EX.A = %h, ID/EX.B = %h",u_mipspipe.IDEXA,u_mipspipe.IDEXB); +     $display("\t ID/EX.op = %h\n",u_mipspipe.IDEXop); +     $display("EX/MEM registers\n\t EX/MEM.rs = %d, EX/MEM.rt = %d",u_mipspipe.IDEXrs,u_mipspipe.IDEXrt,"\n\t EX/MEM.ALUOut = %h, EX/MEM.ALUout = %h",u_mipspipe.EXMEMALUOut,u_mipspipe.EXMEMB); +     $display("\t EX/MEM.op = %h\n",u_mipspipe.EXMEMop); +     $display("MEM/WB registers\n\t MEM/WB.rd = %d, MEM/WB.rt = %d",u_mipspipe.MEMWBrd,u_mipspipe.MEMWBrt,"\n\t MEM/WB.value = %h",u_mipspipe.MEMWBValue); +     $display("\t EX/MEM.op = %h\n",u_mipspipe.MEMWBop); +     end +       +// log to a vcd (variable change dump) file +   initial +      begin +      $dumpfile("test_mipspipe.vcd"); +      $dumpvars; +   end + +endmodule  | 
