在Verilog中模拟LC3-16位处理器

时间:2013-12-26 21:48:39

标签: cpu verilog modelsim lc3

我是Verilog的新手。我正在设计一个LC-3(小型计算机)CPU。我设计了PC单元,控制单元(作为有限状态机),指令存储器,ALU单元和模块中的数据存储器。还有一个作为Main的Register File单元,模块调用在本单元中完成。

问题是当我尝试模拟程序时,只更改我看到的是时钟上升和指令从指令存储器分配给指令线。我希望控制器单元在时钟上升时将值分配给MemRead,PCread,PCwrite等变量,因为当Clk上升时,stateNext被分配给状态。

我的错误是什么?任何帮助和建议都高度评价。以下是我对带控制器单元模块的寄存器文件单元所做的操作:

  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 个答案:

答案 0 :(得分:0)

controlUnit中,更改:

  always @ (posedge state) begin

为:

  always @* begin

你的下一个状态逻辑应该是组合的。 posedge可能将下一状态逻辑视为顺序逻辑。将posedge与4位信号一起使用是非常奇怪的。