Моя плата altera застряла при отображении «8» на цифровом выходе HE0? - PullRequest
0 голосов
/ 08 ноября 2019

Для моего класса «Архитектура компьютера» моему партнеру и мне было поручено реализовать одноцикловый ЦП MIPS и написать программу на C, которая отображала бы 5 и A, чередующиеся в слоте с цифрой HE0 аппаратного обеспечения altera. Мы не уверены, однако, почему наша доска застряла при отображении «8», а не 5 или A. Я новичок в verilog, поэтому я не совсем уверен, что может быть причиной этой ошибки.

mips. v

`timescale 1ns/1ps
`define mydelay 1

// single-cycle MIPS processor
module mips(input         clk, reset,
            output [31:0] pc,
            input  [31:0] instr,
            output        memwrite,
            output [31:0] memaddr,
            output [31:0] memwritedata,
            input  [31:0] memreaddata);

  wire        signext, shiftl16, memtoreg, branch;
  wire        pcsrc, zero;
  wire        alusrc, regdst, regwrite, jump;
  wire [2:0]  alucontrol;

  // Instantiate Controller
  controller c(
    .op         (instr[31:26]),
        .funct      (instr[5:0]),
        .zero       (zero),
        .signext    (signext),
        .shiftl16   (shiftl16),
        .memtoreg   (memtoreg),
        .memwrite   (memwrite),
        .pcsrc      (pcsrc),
        .alusrc     (alusrc),
        .regdst     (regdst),
        .regwrite   (regwrite),
        .jump       (jump),
        .alucontrol (alucontrol));

  // Instantiate Datapath
  datapath dp(
    .clk        (clk),
    .reset      (reset),
    .signext    (signext),
    .shiftl16   (shiftl16),
    .memtoreg   (memtoreg),
    .pcsrc      (pcsrc),
    .alusrc     (alusrc),
    .regdst     (regdst),
    .regwrite   (regwrite),
    .jump       (jump),
    .alucontrol (alucontrol),
    .zero       (zero),
    .pc         (pc),
    .instr      (instr),
    .aluout     (memaddr),
    .writedata  (memwritedata),
    .readdata   (memreaddata));

endmodule

module controller(input  [5:0] op, funct,
                  input        zero,
                  output       signext,
                  output       shiftl16,
                  output       memtoreg, memwrite,
                  output       pcsrc, alusrc,
                  output       regdst, regwrite,
                  output       jump,
                  output [2:0] alucontrol);

  wire [1:0] aluop;
  wire       branch;

  maindec md(
    .op       (op),
    .signext  (signext),
    .shiftl16 (shiftl16),
    .memtoreg (memtoreg),
    .memwrite (memwrite),
    .branch   (branch),
    .alusrc   (alusrc),
    .regdst   (regdst),
    .regwrite (regwrite),
    .jump     (jump),
    .aluop    (aluop));

  aludec ad(
    .funct      (funct),
    .aluop      (aluop),
    .alucontrol (alucontrol));

  assign pcsrc = branch & zero;

endmodule


module maindec(input  [5:0] op,
               output       signext,
               output       shiftl16,
               output       memtoreg, memwrite,
               output       branch, alusrc,
               output       regdst, regwrite,
               output       jump,
               output [1:0] aluop);

  reg [10:0] controls;

  assign {signext, shiftl16, regwrite, regdst, alusrc, branch, memwrite,
          memtoreg, jump, aluop} = controls;

  always @(*)
    case(op)
      6'b000000: controls <= #`mydelay 11'b00110000011; // Rtype
      6'b100011: controls <= #`mydelay 11'b10101001000; // LW
      6'b101011: controls <= #`mydelay 11'b10001010000; // SW
      6'b000100: controls <= #`mydelay 11'b10000100001; // BEQ
      6'b001000,
      6'b001001: controls <= #`mydelay 11'b10101000000; // ADDI, ADDIU: only difference is exception
      6'b001101: controls <= #`mydelay 11'b00101000010; // ORI
      6'b001111: controls <= #`mydelay 11'b01101000000; // LUI
      6'b000010: controls <= #`mydelay 11'b00000000100; // J
      default:   controls <= #`mydelay 11'bxxxxxxxxxxx; // ???
    endcase

endmodule

module aludec(input      [5:0] funct,
              input      [1:0] aluop,
              output reg [2:0] alucontrol);

  always @(*)
    case(aluop)
      2'b00: alucontrol <= #`mydelay 3'b010;  // add
      2'b01: alucontrol <= #`mydelay 3'b110;  // sub
      2'b10: alucontrol <= #`mydelay 3'b001;  // or
      default: case(funct)          // RTYPE
          6'b100000,
          6'b100001: alucontrol <= #`mydelay 3'b010; // ADD, ADDU: only difference is exception
          6'b100010,
          6'b100011: alucontrol <= #`mydelay 3'b110; // SUB, SUBU: only difference is exception
          6'b100100: alucontrol <= #`mydelay 3'b000; // AND
          6'b100101: alucontrol <= #`mydelay 3'b001; // OR
          6'b101010,
          6'b101011: alucontrol <= #`mydelay 3'b111; // SLT, SLTU **added
          default:   alucontrol <= #`mydelay 3'bxxx; // ???
        endcase
    endcase

endmodule

module datapath(input         clk, reset,
                input         signext,
                input         shiftl16,
                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, shiftedimm;
  wire [31:0] srca, srcb;
  wire [31:0] result;
  wire        shift;

  // next PC logic
  flopr #(32) pcreg(
    .clk   (clk),
    .reset (reset),
    .d     (pcnext),
    .q     (pc));

  adder pcadd1(
    .a (pc),
    .b (32'b100),
    .y (pcplus4));

  sl2 immsh(
    .a (signimm),
    .y (signimmsh));

  adder pcadd2(
    .a (pcplus4),
    .b (signimmsh),
    .y (pcbranch));

  mux2 #(32) pcbrmux(
    .d0  (pcplus4),
    .d1  (pcbranch),
    .s   (pcsrc),
    .y   (pcnextbr));

  mux2 #(32) pcmux(
    .d0   (pcnextbr),
    .d1   ({pcplus4[31:28], instr[25:0], 2'b00}),
    .s    (jump),
    .y    (pcnext));

  // register file logic
  regfile rf(
    .clk     (clk),
    .we      (regwrite),
    .ra1     (instr[25:21]),
    .ra2     (instr[20:16]),
    .wa      (writereg),
    .wd      (result),
    .rd1     (srca),
    .rd2     (writedata));

  mux2 #(5) wrmux(
    .d0  (instr[20:16]),
    .d1  (instr[15:11]),
    .s   (regdst),
    .y   (writereg));

  mux2 #(32) resmux(
    .d0 (aluout),
    .d1 (readdata),
    .s  (memtoreg),
    .y  (result));

  sign_zero_ext sze(
    .a       (instr[15:0]),
    .signext (signext),
    .y       (signimm[31:0]));

  shift_left_16 sl16(
    .a         (signimm[31:0]),
    .shiftl16  (shiftl16),
    .y         (shiftedimm[31:0]));

  // ALU logic
  mux2 #(32) srcbmux(
    .d0 (writedata),
    .d1 (shiftedimm[31:0]),
    .s  (alusrc),
    .y  (srcb));

  alu alu(
    .a       (srca),
    .b       (srcb),
    .alucont (alucontrol),
    .result  (aluout),
    .zero    (zero));

endmodule

mipsparts.v

`timescale 1ns/1ps
`define mydelay 1

`define REGFILE_FF
`ifdef REGFILE_FF

module regfile(input             clk, 
               input             we, 
               input      [4:0]  ra1, ra2, wa, 
               input      [31:0] wd, 
               output reg [31:0] rd1, rd2);

    reg [31:0] R1;
    reg [31:0] R2;
    reg [31:0] R3;
    reg [31:0] R4;
    reg [31:0] R5;
    reg [31:0] R6;
    reg [31:0] R7;
    reg [31:0] R8;
    reg [31:0] R9;
    reg [31:0] R10;
    reg [31:0] R11;
    reg [31:0] R12;
    reg [31:0] R13;
    reg [31:0] R14;
    reg [31:0] R15;
    reg [31:0] R16;
    reg [31:0] R17;
    reg [31:0] R18;
    reg [31:0] R19;
    reg [31:0] R20;
    reg [31:0] R21;
    reg [31:0] R22;
    reg [31:0] R23;
    reg [31:0] R24;
    reg [31:0] R25;
    reg [31:0] R26;
    reg [31:0] R27;
    reg [31:0] R28;
    reg [31:0] R29;
    reg [31:0] R30;
    reg [31:0] R31;

    always @(posedge clk)
    begin
     if (we) 
     begin
        case (wa[4:0])
        5'd0:   ;
        5'd1:   R1  <= wd;
        5'd2:   R2  <= wd;
        5'd3:   R3  <= wd;
        5'd4:   R4  <= wd;
        5'd5:   R5  <= wd;
        5'd6:   R6  <= wd;
        5'd7:   R7  <= wd;
        5'd8:   R8  <= wd;
        5'd9:   R9  <= wd;
        5'd10:  R10 <= wd;
        5'd11:  R11 <= wd;
        5'd12:  R12 <= wd;
        5'd13:  R13 <= wd;
        5'd14:  R14 <= wd;
        5'd15:  R15 <= wd;
        5'd16:  R16 <= wd;
        5'd17:  R17 <= wd;
        5'd18:  R18 <= wd;
        5'd19:  R19 <= wd;
        5'd20:  R20 <= wd;
        5'd21:  R21 <= wd;
        5'd22:  R22 <= wd;
        5'd23:  R23 <= wd;
        5'd24:  R24 <= wd;
        5'd25:  R25 <= wd;
        5'd26:  R26 <= wd;
        5'd27:  R27 <= wd;
        5'd28:  R28 <= wd;
        5'd29:  R29 <= wd;
        5'd30:  R30 <= wd;
        5'd31:  R31 <= wd;
        endcase
     end
    end

    always @(*)
    begin
        case (ra2[4:0])
        5'd0:   rd2 = 32'b0;
        5'd1:   rd2 = R1;
        5'd2:   rd2 = R2;
        5'd3:   rd2 = R3;
        5'd4:   rd2 = R4;
        5'd5:   rd2 = R5;
        5'd6:   rd2 = R6;
        5'd7:   rd2 = R7;
        5'd8:   rd2 = R8;
        5'd9:   rd2 = R9;
        5'd10:  rd2 = R10;
        5'd11:  rd2 = R11;
        5'd12:  rd2 = R12;
        5'd13:  rd2 = R13;
        5'd14:  rd2 = R14;
        5'd15:  rd2 = R15;
        5'd16:  rd2 = R16;
        5'd17:  rd2 = R17;
        5'd18:  rd2 = R18;
        5'd19:  rd2 = R19;
        5'd20:  rd2 = R20;
        5'd21:  rd2 = R21;
        5'd22:  rd2 = R22;
        5'd23:  rd2 = R23;
        5'd24:  rd2 = R24;
        5'd25:  rd2 = R25;
        5'd26:  rd2 = R26;
        5'd27:  rd2 = R27;
        5'd28:  rd2 = R28;
        5'd29:  rd2 = R29;
        5'd30:  rd2 = R30;
        5'd31:  rd2 = R31;
        endcase
    end

    always @(*)
    begin
        case (ra1[4:0])
        5'd0:   rd1 = 32'b0;
        5'd1:   rd1 = R1;
        5'd2:   rd1 = R2;
        5'd3:   rd1 = R3;
        5'd4:   rd1 = R4;
        5'd5:   rd1 = R5;
        5'd6:   rd1 = R6;
        5'd7:   rd1 = R7;
        5'd8:   rd1 = R8;
        5'd9:   rd1 = R9;
        5'd10:  rd1 = R10;
        5'd11:  rd1 = R11;
        5'd12:  rd1 = R12;
        5'd13:  rd1 = R13;
        5'd14:  rd1 = R14;
        5'd15:  rd1 = R15;
        5'd16:  rd1 = R16;
        5'd17:  rd1 = R17;
        5'd18:  rd1 = R18;
        5'd19:  rd1 = R19;
        5'd20:  rd1 = R20;
        5'd21:  rd1 = R21;
        5'd22:  rd1 = R22;
        5'd23:  rd1 = R23;
        5'd24:  rd1 = R24;
        5'd25:  rd1 = R25;
        5'd26:  rd1 = R26;
        5'd27:  rd1 = R27;
        5'd28:  rd1 = R28;
        5'd29:  rd1 = R29;
        5'd30:  rd1 = R30;
        5'd31:  rd1 = R31;
        endcase
    end

endmodule

`else

module regfile(input         clk, 
               input         we, 
               input  [4:0]  ra1, ra2, wa, 
               input  [31:0] wd, 
               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 (we) rf[wa] <= #`mydelay wd; 

  assign #`mydelay rd1 = (ra1 != 0) ? rf[ra1] : 0;
  assign #`mydelay rd2 = (ra2 != 0) ? rf[ra2] : 0;
endmodule

`endif


module alu(input      [31:0] a, b, 
           input      [2:0]  alucont, 
           output reg [31:0] result,
           output            zero);

  wire [31:0] b2, sum, slt, sltu;
  wire        N, Z, C, V;

  assign b2 = alucont[2] ? ~b:b; 

  adder_32bit iadder32 (.a   (a),
                                .b   (b2),
                                .cin (alucont[2]),
                                .sum (sum),
                                .N   (N),
                                .Z   (Z),
                                .C   (C),
                                .V   (V));

  // signed less than ("N set and V clear" OR "N clear and V set")
  assign slt  = N ^ V ; 

  // unsigned lower (C clear) 
  assign sltu = ~C ;   

  always@(*)
    case(alucont[1:0])
      2'b00: result <= #`mydelay a & b;
      2'b01: result <= #`mydelay a | b;
      2'b10: result <= #`mydelay sum;
      2'b11: result <= #`mydelay slt;
    endcase

  assign #`mydelay zero = (result == 32'b0);

endmodule


module adder_32bit (input  [31:0] a, b, 
                    input         cin,
                    output [31:0] sum,
                    output        N,Z,C,V);

    wire [31:0]  ctmp;

    assign N = sum[31];
    assign Z = (sum == 32'b0);
    assign C = ctmp[31];
    assign V = ctmp[31] ^ ctmp[30];

    adder_1bit bit31 (.a(a[31]), .b(b[31]), .cin(ctmp[30]), .sum(sum[31]), .cout(ctmp[31]));
    adder_1bit bit30 (.a(a[30]), .b(b[30]), .cin(ctmp[29]), .sum(sum[30]), .cout(ctmp[30]));
    adder_1bit bit29 (.a(a[29]), .b(b[29]), .cin(ctmp[28]), .sum(sum[29]), .cout(ctmp[29]));
    adder_1bit bit28 (.a(a[28]), .b(b[28]), .cin(ctmp[27]), .sum(sum[28]), .cout(ctmp[28]));
    adder_1bit bit27 (.a(a[27]), .b(b[27]), .cin(ctmp[26]), .sum(sum[27]), .cout(ctmp[27]));
    adder_1bit bit26 (.a(a[26]), .b(b[26]), .cin(ctmp[25]), .sum(sum[26]), .cout(ctmp[26]));
    adder_1bit bit25 (.a(a[25]), .b(b[25]), .cin(ctmp[24]), .sum(sum[25]), .cout(ctmp[25]));
    adder_1bit bit24 (.a(a[24]), .b(b[24]), .cin(ctmp[23]), .sum(sum[24]), .cout(ctmp[24]));
    adder_1bit bit23 (.a(a[23]), .b(b[23]), .cin(ctmp[22]), .sum(sum[23]), .cout(ctmp[23]));
    adder_1bit bit22 (.a(a[22]), .b(b[22]), .cin(ctmp[21]), .sum(sum[22]), .cout(ctmp[22]));
    adder_1bit bit21 (.a(a[21]), .b(b[21]), .cin(ctmp[20]), .sum(sum[21]), .cout(ctmp[21]));
    adder_1bit bit20 (.a(a[20]), .b(b[20]), .cin(ctmp[19]), .sum(sum[20]), .cout(ctmp[20]));
    adder_1bit bit19 (.a(a[19]), .b(b[19]), .cin(ctmp[18]), .sum(sum[19]), .cout(ctmp[19]));
    adder_1bit bit18 (.a(a[18]), .b(b[18]), .cin(ctmp[17]), .sum(sum[18]), .cout(ctmp[18]));
    adder_1bit bit17 (.a(a[17]), .b(b[17]), .cin(ctmp[16]), .sum(sum[17]), .cout(ctmp[17]));
    adder_1bit bit16 (.a(a[16]), .b(b[16]), .cin(ctmp[15]), .sum(sum[16]), .cout(ctmp[16]));
    adder_1bit bit15 (.a(a[15]), .b(b[15]), .cin(ctmp[14]), .sum(sum[15]), .cout(ctmp[15]));
    adder_1bit bit14 (.a(a[14]), .b(b[14]), .cin(ctmp[13]), .sum(sum[14]), .cout(ctmp[14]));
    adder_1bit bit13 (.a(a[13]), .b(b[13]), .cin(ctmp[12]), .sum(sum[13]), .cout(ctmp[13]));
    adder_1bit bit12 (.a(a[12]), .b(b[12]), .cin(ctmp[11]), .sum(sum[12]), .cout(ctmp[12]));
    adder_1bit bit11 (.a(a[11]), .b(b[11]), .cin(ctmp[10]), .sum(sum[11]), .cout(ctmp[11]));
    adder_1bit bit10 (.a(a[10]), .b(b[10]), .cin(ctmp[9]),  .sum(sum[10]), .cout(ctmp[10]));
    adder_1bit bit9  (.a(a[9]),  .b(b[9]),  .cin(ctmp[8]),  .sum(sum[9]),  .cout(ctmp[9]));
    adder_1bit bit8  (.a(a[8]),  .b(b[8]),  .cin(ctmp[7]),  .sum(sum[8]),  .cout(ctmp[8]));
    adder_1bit bit7  (.a(a[7]),  .b(b[7]),  .cin(ctmp[6]),  .sum(sum[7]),  .cout(ctmp[7]));
    adder_1bit bit6  (.a(a[6]),  .b(b[6]),  .cin(ctmp[5]),  .sum(sum[6]),  .cout(ctmp[6]));
    adder_1bit bit5  (.a(a[5]),  .b(b[5]),  .cin(ctmp[4]),  .sum(sum[5]),  .cout(ctmp[5]));
    adder_1bit bit4  (.a(a[4]),  .b(b[4]),  .cin(ctmp[3]),  .sum(sum[4]),  .cout(ctmp[4]));
    adder_1bit bit3  (.a(a[3]),  .b(b[3]),  .cin(ctmp[2]),  .sum(sum[3]),  .cout(ctmp[3]));
    adder_1bit bit2  (.a(a[2]),  .b(b[2]),  .cin(ctmp[1]),  .sum(sum[2]),  .cout(ctmp[2]));
    adder_1bit bit1  (.a(a[1]),  .b(b[1]),  .cin(ctmp[0]),  .sum(sum[1]),  .cout(ctmp[1]));
    adder_1bit bit0  (.a(a[0]),  .b(b[0]),  .cin(cin),      .sum(sum[0]),  .cout(ctmp[0]));

endmodule


module adder_1bit (input a, b, cin,
                   output sum, cout);

  assign sum  = a ^ b ^ cin;
  assign cout = (a & b) | (a & cin) | (b & cin);

endmodule


module adder(input [31:0] a, b,
             output [31:0] y);

  assign #`mydelay y = a + b;
endmodule



module sl2(input  [31:0] a,
           output [31:0] y);

  // shift left by 2
  assign #`mydelay y = {a[29:0], 2'b00};
endmodule



module sign_zero_ext(input      [15:0] a,
                     input             signext,
                     output reg [31:0] y);

   always @(*)
    begin
       if (signext)  y <= {{16{a[15]}}, a[15:0]};
       else          y <= {16'b0, a[15:0]};
    end

endmodule



module shift_left_16(input      [31:0] a,
                       input         shiftl16,
                     output reg [31:0] y);

   always @(*)
    begin
       if (shiftl16) y = {a[15:0],16'b0};
       else          y = a[31:0];
    end

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 <= #`mydelay 0;
    else       q <= #`mydelay d;

endmodule



module flopenr #(parameter WIDTH = 8)
                (input                  clk, reset,
                 input                  en,
                 input      [WIDTH-1:0] d, 
                 output reg [WIDTH-1:0] q);

  always @(posedge clk, posedge reset)
    if      (reset) q <= #`mydelay 0;
    else if (en)    q <= #`mydelay d;

endmodule



module mux2 #(parameter WIDTH = 8)
             (input  [WIDTH-1:0] d0, d1, 
              input              s, 
              output [WIDTH-1:0] y);

  assign #`mydelay y = s ? d1 : d0; 

endmodule

SevenSeg.c (c исходный код)

#include "SevenSeg.h"

int SevenSeg()
{
unsigned int * seg0_addr = (unsigned int *) SevenSeg0;
unsigned int i;

while (1){

     *seg0_addr = SEG_5;
     for (i=0; i<0xFFFFF; i++) ;

     *seg0_addr = SEG_A;
     for (i=0; i<0xFFFFF; i++) ;
}

return 0;
}

Ожидаемый результат на нашей плате альтера: 0005 -> positive_clk-> 000A -> positive_clk (повторяется навсегда) Фактическая мощность на борту: 0008

...