Неправильная симуляция 16-битного процессора LC-3 в Verilog

Я работаю над проектированием процессора LC-3 (маленький компьютер). Я разработал блок ПК, блок управления (как конечный автомат), память инструкций, блок ALU и память данных в модулях. Существует также блок Register File, который работает как основной, в этом блоке выполняются вызовы модулей.

Я хочу, чтобы программа работала так, как когда PCread равен 1, получаю переменную, которая будет назначена out, из переменной in, а когда PCwrite равен 1, просто увеличиваю переменную out. out — это адрес, отправленный в память инструкций.

Проблема в том, что когда я имитирую, инструкция никогда не загружается в память инструкций. Потому что PCwrite не работает для первого состояния блока управления, потому что я сбрасываю переменные PCread и PCread в первом состоянии. Я делаю это, потому что я не хочу, чтобы инструкция загружалась, пока одна инструкция не закончит свою работу. Я не мог найти способ справиться с этим.

Я знаю, что если это решено, процессор будет работать, потому что, когда я пробую его для одной инструкции с инициализированными значениями, он работает.

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;
  wire InsMemRead;
  
  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;
  
  initial begin
    mux5out=16'hFFFF;
  end

  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,InsMemRead,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(Clk,address,InsMemRead,instruction);
  
  always @* 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,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);
  
  input Clk;
  input [15:0] in;
  output reg mux1,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
  output reg [1:0] mux2;
  reg [3:0] state,stateNext;
  
  reg counter;
  output wire [2:0] rd1,rd2,wr;
  
  initial begin
    state=4'b0000;
    stateNext=4'b0001;
    MemRead=0;
    
    PCwrite=1;
  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;
      PCwrite=0;
      PCread=0;
    end
    if(state==4'b0001)
      begin
      InsMemRead<=1;
    if(in[15:12]==4'b0100)begin
      stateNext=4'b0100;
      InsMemRead=1'b1;
    end
    else if( in[15:12]==4'b1000)begin
      stateNext=4'b0100;
      InsMemRead=1;
    end
      else if(in[15:12]==4'b0010)begin
      stateNext=4'b0010;
      InsMemRead=1;
    end
      else if(in[15:12]==4'b1100)begin
      stateNext=4'b1100;
      InsMemRead=1;
    end
      else if(in[15:12]==1010)begin
      stateNext=4'b1010;
      InsMemRead=1;
    end
  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;
      mux5=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;
      PCread=1;
      
    end
  end
  always @(posedge Clk) begin
      state = stateNext;
  end
  
endmodule

module PCunit(Clk,PCwrite,PCread,in,out);
  input Clk,PCread,PCwrite;
   
  input wire [15:0] in;
  output reg [15:0] out;
  
  
always @(posedge Clk) begin
        
      if(PCwrite)
      begin
      out<=out+1; 
       end
      else
      begin
       if(PCread)
      begin
      out<=in;
      end 
      end
    end
    
endmodule

module ALU(in1,in2,ALUout,ALUcontrol);
  input ALUcontrol;
  input wire [15:0] in1, in2;
  output reg [15:0] ALUout;
  
    always @* begin
    if(ALUcontrol) 
      
    ALUout = in1 + in2;

else
    ALUout = in1 & in2; 

end
  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 @* begin
    if(MemRead) begin
      out=Mem[AddrReg];
      end
      end
  
endmodule

module InstructionMemory(Clk,address,InsMemRead,instruction);
  input Clk;
  input [15:0] address;
  input InsMemRead;
  output reg [15:0] instruction;
  
  reg [15:0] InstructionMemory [15:0];
  
  initial begin
    $readmemh("AssemblerOutput.hex", InstructionMemory);
  end
  
  always@(posedge Clk)begin
    if(InsMemRead)
  instruction=InstructionMemory[address];
end
endmodule
  

person Bar    schedule 27.12.2013    source источник


Ответы (2)


Всегда используйте @* для списков конфиденциальности для комбинированной логики. Изменять:

  always @(MemRead) begin

to:

  always @* begin

Ваш блок always не чувствителен к изменениям в AddrReg.

person toolic    schedule 27.12.2013

Я обнаружил, что одним из способов решения этой проблемы является отправка сигнала с блока ПК на блок управления о том, что адрес инструкции отправляется в память инструкций с выходной переменной reg, и проверьте, не изменилась ли эта переменная в блоке управления, если да, сбросьте переменная PCwrite. Спасибо всем пытался помочь.

person Bar    schedule 28.12.2013