1
votes

I am a newbie in Verilog. I am working on designing a LC-3(Little Computer) CPU. I have designed PC unit, Control Unit(as Finite State Machine), Instruction Memory, ALU unit and Data Memory in Modules. There is also a Register File unit which works as Main, module calls are done in this unit.

The problem is when I try to simulate the program, only change that I saw is Clock rises and the Instruction assign to the Instruction wire from the Instruction Memory. I expect the Controller Unit assign the values to the variables like MemRead, PCread, PCwrite etc. at the clock rises, because as Clk rises, stateNext is assigned to the state.

What could be my mistake? Any helps and suggestions are highly appriciated. Here is what I done with the Register File Unit with Controller Unit module:

  module reg_fileandMain();

  parameter B=16, W=3;

  reg Clk;
  wire wr_en;
  wire [W-1:0] w_addr, r_addr1, r_addr2;
  wire [B-1:0] inData;
  wire [B-1:0] r_data1;
  wire [B-1:0] r_data2;
  wire [B-1:0] address;
  wire Dataout;

  reg [15:0] extended, mux1out, mux2out, mux3out, mux4out, mux5out;
  wire ALUout, incrementer;
  wire [15:0] instruction;
  reg [B-1:0] array_reg[2**W-1:0];
  wire mux1,mux3,mux4,mux5;
  wire [1:0] mux2;


  wire MemRead,PCwrite,ALUcontrol,MemWrite,PCread;

  always@(posedge Clk)
  begin
  if(wr_en)begin
    array_reg[w_addr]<=inData;
  end
  end
  assign r_data1=array_reg[r_addr1];
  assign r_data2=array_reg[r_addr2];

  controlUnit controlUnit0(Clk,instruction,mux1,mux2,mux3,mux4,mux5,MemRead,PCwrite,wr_en,ALUcontrol,MemWrite,PCread,r_addr1,r_addr2,w_addr);

  PCunit PCunit0(Clk,PCwrite,PCread,mux5out,address);

  DataMem DataMem0(Clk,mux2out,r_data1,MemRead,MemWrite,Dataout);

  ALU ALU0(mux1out,r_data2,ALUout,ALUcontrol);

  InstructionMemory InstructionMemory0(address,instruction);

  always @(mux1,mux2,mux3,mux4,mux5) begin
  if(mux1)begin
    extended = { {11{instruction[4]}}, instruction[4:0] };
    mux1out=extended;
  end
  else begin
    mux1out=r_data1;
  end

  if(mux2==2'b00)begin
    mux2out=ALUout;
    end
  else if(mux2==2'b01)begin
    extended = instruction[8:0];
    mux2out=extended;
    end
  else if(mux2==2'b11)begin
    extended = instruction[8:0];
    mux2out=extended;
    end

  if(mux3)begin
    mux3out=mux2out;
    end
  else begin
    mux3out=Dataout;
    end

  if(mux4)begin
    mux4out=address;
    end
  else begin
    mux4out=mux3out;
    end

  if(mux5)begin
    mux5out=address;
    end
  else begin
    mux5out=mux3out;
    end 

end

   assign inData=mux4out;
       always begin
   #20 Clk<=0;
   #20 Clk<=1;
 end

endmodule

  module controlUnit(Clk,in,mux1,mux2,mux3,mux4,mux5,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);

  input Clk;
  input [15:0] in;
  output reg mux1,mux3,mux4,mux5,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
  output reg [1:0] mux2;
  reg [3:0] state,stateNext;

  output wire [2:0] rd1,rd2,wr;

  initial begin
    state=4'b0111;
    stateNext=4'b0000;
    MemRead=0;
  end

  assign rd1=in[2:0];
  assign rd2=in[8:6];
  assign wr=in[11:9];

  always @* begin
    if (state==4'b0000)begin
      stateNext=4'b0001;
      PCread=1;
    end
    else if(state==4'b0001 && in[15:12]==0100)begin
      stateNext=4'b0100;
      MemRead=1;
    end
    else if(state==4'b0001 && in[15:12]==1000)begin
      stateNext=4'b0100;
      MemRead=1;
    end
      else if(state==4'b0001 && in[15:12]==0010)begin
      stateNext=4'b0010;
      MemRead=1;
    end
      else if(state==4'b0001 && in[15:12]==1100)begin
      stateNext=4'b1100;
      MemRead=1;
    end
      else if(state==4'b0001 && in[15:12]==1010)begin
      stateNext=4'b1010;
      MemRead=1;
    end
    else if(state==4'b0100)begin
      stateNext=4'b0101;
    end
    else if(state==4'b0101)begin
      stateNext=4'b0000;
      mux3=0;
      mux4=0; 
      WE=1; 
      mux2<=2'b01; 
      MemRead=1;
      PCwrite=1;
    end
    else if(state==4'b1000)begin
      stateNext=4'b0000;
      mux1=in[5];
      ALUcontrol=0; 
      mux3=1;
      mux4=0;
      WE=1;
      PCwrite=1;
    end
    else if(state==4'b0010)begin
      stateNext=4'b0000;
      mux1=in[5];
      ALUcontrol=1;
      mux3=1;
      mux4=0;
      WE=1;
      PCwrite=1;
    end
      else if(state==4'b1100)begin
      stateNext=4'b0000;
      mux2<=2'b01;
      MemWrite=1;
      PCwrite=1;
    end
    else if(state==4'b1010)begin
      stateNext=4'b0000;
      mux2<=2'b11;
      mux3=1;
      mux5=0;
      PCwrite=1;
    end
  end
  always @(posedge Clk) begin
      state = stateNext;
  end

  endmodule


   module ALU(in1,in2,ALUout,ALUcontrol);
  input ALUcontrol;
  input wire [15:0] in1, in2;
  output reg [15:0] ALUout;

    always @(in1, in2) begin
    if(ALUcontrol) 

    ALUout = in1 + in2;

else
    ALUout = in1 & in2; 

end
  endmodule

module InstructionMemory(address,instruction);
  input [15:0] address;
  output [15:0] instruction;

  reg [15:0] InstructionMemory [15:0];

  initial begin
    $readmemh("AssemblerOutput.hex", InstructionMemory);
  end

  assign instruction=InstructionMemory[address];

endmodule

module DataMem(Clk,AddrReg,in,MemRead,MemWrite,out);
  input Clk, MemRead, MemWrite;
  input [15:0] AddrReg, in;
  output reg [15:0] out;

  reg[15:0] Mem[2**9:0];

  always @(posedge Clk) begin
    if(MemWrite)begin
      Mem[AddrReg]=in;
    end
  end

  always @(MemRead) begin
    if(MemRead) begin
      out=Mem[AddrReg];
      end
      end

endmodule


module PCunit(Clk,PCwrite,PCread,in,out);
  input Clk,PCwrite,PCread;
  input wire [15:0] in;
  output reg [15:0] out;

  initial begin
    out=16'h0000;
    end

always @(posedge Clk) begin
    if(PCwrite==1)begin
      out=out+1;
    end
    if(PCread==1)begin
      out=in;
    end
  end


endmodule
1

1 Answers

0
votes

In controlUnit, change:

  always @ (posedge state) begin

to:

  always @* begin

Your next-state logic should be combinational. The posedge might treat the next-state logic as sequential. It is very strange to use posedge with a 4-bit signal.