-1

I'm writing a verilog code where i'm reading two files and saving those numbers into registers. I'm then multiplying them and adding them. Pretty much a Multiplication Accumulator. However i'm having a hard frustrating time with the code that i have. It read the numbers from the files correctly and it multiples but here is the problem? When i first run it using ModelSim, I reset everything so i can clear out the accumulator. I then begin the program, but there is always this huge delay in my "macc_out" and i cannot seem to figure out why. This delay should not be there and instead it should be getting the result out A*B+MAC. Even after the delay, it's not getting the correct output. My second problem is that if i go from reset high, to low (start the program) and then back to reset high ( to reset all my values), they do not reset! This is frustrating since i've been working on this for a week and don't know/can't see a bug. Im asking for an extra set of eyes to see if you can spot my mistake. Attached is my code with the instantiations and also my ModelSim functional Wave Form. Any help is appreciated!

    module FSM(clk,start,reset,done,clock_count);
    input clk, start, reset;
    output reg done;
    output reg[10:0] clock_count;
    reg [0:0] macc_clear;
    reg[5:0] Aread, Bread, Cin;
    wire signed [7:0] a, b;
    wire signed [18:0] macc_out;
    reg [3:0] i,j,m;
    reg add;
    reg [0:0] go;
    reg[17:0] c;
    parameter n = 8;
    reg[1:0] state;


    reg [1:0] S0 = 2'b00;
    reg [1:0] S1 = 2'b01;
    reg [1:0] S2 = 2'b10;
    reg [1:0] S3 = 2'b11;



    ram_A Aout(.clk(clk), .addr(Aread), .q(a));
    ram_B Bout(.clk(clk), .addr(Bread), .q(b));
    mac macout(.clk(clk), .macc_clear(macc_clear), .A(a), .B(b), .macc_out(macc_out), .add(add));
    ram_C C_in(.clk(clk), .addr(Cin), .q(c));




    always @(posedge clk) begin

            if (reset == 1) begin
                i <= 0;
                add<=0;
                j <= 0;
                m <= 0;
                clock_count <= 0;
                go <= 0;
                macc_clear<=1;
            end
            else
                state<=S0;


                case(state) 


                S0: begin
    //              if (reset) begin
    //                  i <= 0;
    //                  add<=0;
    //                  j <= 0;
    //                  m <= 0;
    //                  clock_count <= 0;
    //                  go <= 0;
    //                  macc_clear<=1;
    //                  state <= S0;
    //              end         
                        macc_clear<=1;
                        done<=0;
                        state <= S1;
                        end

                S1: begin
                    add<=1;
                    macc_clear<=0;
                    clock_count<=clock_count+1;
                    m<=m+1;
                    Aread <= 8*m + i;
                    Bread <= 8*j + m;
                    if (m==7) begin
                        state <= S2;
                        macc_clear<=1;
                        add<=0;
                    end

                    else
                        state <=S1;

                    end



                S2: begin
                    add<=1;
                    macc_clear<=0;
                    m<=0;
                    i<=i+1;
                    if (i<7)
                        state<=S1;
                    else if (i==8) begin
                        state<=S3;
                        add<=0;
                end
                end



                S3: begin
                    add<=1;
                    i<=0;
                    j<=j+1;
                    if(j<7)
                        state<=S1;
                    else begin
                        state<=S0;
                        done<=1;
                        add<=0;
                end
                end


    endcase

    end


    always @ (posedge macc_clear) begin
        Cin <= 8*j + i;
        c <= macc_out;
    end

    endmodule



    module mac(clk, macc_clear, A, B, macc_out, add);

  input clk, macc_clear;
  input signed [7:0] A, B;
  input add;
  output reg signed [18:0] macc_out;
  reg signed [18:0] MAC;

  always @( posedge clk) begin

  if (macc_clear) begin
    macc_out <= MAC;
    MAC<=0;
  end

else if (add) begin
    MAC<=(A*B)+ MAC;
    macc_out<=MAC;
    end

end
endmodule



module ram_A( clk, addr,q);
    output reg[7:0] q;
    input [5:0] addr;
    input clk;
    reg [7:0] mem [0:63];
  initial begin
  $readmemb("ram_a_init.txt", mem);
        end

     always @(posedge clk) begin
            q <= mem[addr];
    end
endmodule



module ram_C(clk,addr, q);
    input [18:0] q;
    input [5:0] addr;
    input clk;
    reg [18:0] mem [0:63];



    always @(posedge clk) begin
                mem[addr] <= q;
    end
endmodule

ModelSim Functional Simulation Wave Form

user3859049
  • 29
  • 1
  • 1
  • 3

1 Answers1

-1

1) Take a look at the schematic view for your MACC module - I think some of your "problems" will be obvious from that;
2) Consider using an always@(*) (Combinational) block for your FSM control signals (stuff like add or macc_clear) rather than a always@(posedge clk) (sequential) - it makes the logic to assert them easier. Right now they're registered, so you have a cycle delay. ;
3) In your MAC, you clear the MAC register on a reset, but you don't clear the macc_out register.

In short, I think you need to step back, and consider which signals are combinational logic, and which ones are sequential and need to be in registers.

wilcroft
  • 1,580
  • 2
  • 14
  • 20