Search code examples
verilogcpu-architecture

Verilog simple cpu doesn't work


I am trying to create a simple cpu using verilog but i couldn't. I am using a logisim circuit as starting point.

This is the cpu desing. http://a1202.hizliresim.com/u/v/31szg.png

This is the control unit http://c1202.hizliresim.com/u/r/2yrng.png

This code doesn't work . Where is the problem?

thanks for any help

module simplecpu
(
input clk,
output wire s_out0,
output wire s_out1,
output wire s_out2,
output wire s_out3,
output wire s_out4,
output wire s_out5,
output wire s_out6,
output wire s_out7

);

wire  w_arload,w_pcload,w_pcinc,w_drload,w_acload,w_acinc,w_irload,read,drbus,pcbus,membus,alusel;
wire [5:0] win_ar,win_pc,w_ar_to_mem,pc_to_bus;
wire [7:0] win_dr,win_dr_alu,win_ac_alu,win_ac,data_bus,dr_to_bus,mem_to_bus;
wire[1:0] win_ir,irtorom;

wire [11:0] fromcontrol;//0 read,11 arload
assign read = fromcontrol[0];
assign drbus = fromcontrol[1];
assign pcbus = fromcontrol[2];
assign membus = fromcontrol[3];
assign alusel = fromcontrol[4];
assign w_irload = fromcontrol[5];
assign w_acinc = fromcontrol[6];
assign w_acload = fromcontrol[7];
assign w_drload = fromcontrol[8];
assign w_pcinc = fromcontrol[9];
assign w_pcload = fromcontrol[10];
assign w_arload = fromcontrol[11];




controlunit mycontrol  (.clk(clk), .ir(irtorom), .controls(fromcontrol));
alu myalu (.ac(win_ac_alu), .dr(win_dr_alu), .sel(alusel), .toAC(win_ac));
ar_register my_ar (.out(w_ar_to_mem), .in(win_ar), .arload(w_arload), .clk(clk));
pc_register my_pc (.out(pc_to_bus), .in(win_pc), .pcload(w_pcload), .clk(clk), .pcinc(w_pcinc));
dr_register my_dr (.out(dr_to_bus), .in(win_dr), .drload(w_drload), .clk(clk));
ac_register my_ac(.out(win_ac_alu), .in(win_ac), .acload(w_acload), .acinc(w_acinc), .clk(clk));
ir_register my_ir(.out(irtorom), .in(win_ir), .irload(w_irload), .clk(clk));
main_rom my_rom (.address(w_ar_to_mem), .data(mem_to_bus));



assign s_out0 = win_ac_alu[0];
assign s_out1 = win_ac_alu[1];
assign s_out2 = win_ac_alu[2];
assign s_out3 = win_ac_alu[3];
assign s_out4 = win_ac_alu[4];
assign s_out5 = win_ac_alu[5];
assign s_out6 = win_ac_alu[6];
assign s_out7 = win_ac_alu[7];

assign win_ar[5:0] = data_bus[5:0];
assign win_pc[5:0] = data_bus[5:0];
assign win_dr[7:0] = data_bus[7:0];
assign win_ir[1:0] = data_bus[7:6];

assign data_bus = (membus) ? mem_to_bus : 8'bz;
assign data_bus [5:0] = (pcbus)     ? pc_to_bus : 6'bz;
assign data_bus = (drbus) ? dr_to_bus : 8'bz;

endmodule






module ac_register (out, in, acload, acinc, clk);
  parameter n = 8;

  output [n-1:0] out;
  input [n-1:0] in;
  input acload;
   input clk;
  input acinc;
  reg [n-1:0] out;

  always @(posedge clk) 
    begin 
    if (acload) 
        out = in; 
        else if (acinc)
        out = out+ 5'h1;
    end 
endmodule 









module alu (ac, dr, sel, toAC  );

input [7:0] ac,dr;
output[7:0] toAC;
reg [7:0] toAC;
input sel;
always @(sel or ac or dr ) 
if (sel==1'b1) 
begin
  toAC = ac+dr;
end
 else
 begin
 toAC = ac && dr;
end
endmodule





module ar_register (out, in, arload, clk);
  parameter n = 6;

  output [n-1:0] out;
  input [n-1:0] in;
  input arload;
  input clk;

  reg [n-1:0] out;

  always @(posedge clk) 
    begin 
    if (arload) 
        out = in; 
    end 
endmodule 



module controlunit
(
clk,
ir,
controls
);

input clk;
input  [1:0] ir;
output  [11:0] controls;
wire [16:0] fromrom;

wire [3:0]  alttomux,muxtod,dtoalt,tomuxone;
wire alttosel;

assign tomuxone[2:1] = ir;
assign tomuxone[3] = 0;
assign tomuxone[0] = 0;

dflipflop myflipflop  (.data(muxtod[3:0]), .clk(clk), .q(dtoalt[3:0]));
mux mymux (.a(alttomux[3:0]), .b(tomuxone[3:0]), .s(alttosel));
enaltrom myrom (.address(dtoalt), .data(fromrom));


assign controls [11:0] = fromrom[15:4];
assign alttomux [3:0] = fromrom [3:0];
assign alttosel = fromrom[16];


endmodule




module dr_register (out, in, drload, clk);
  parameter n = 8;

  output [n-1:0] out;
  input [n-1:0] in;
  input drload;

  input clk;

  reg [n-1:0] out;

  always @(posedge clk) 
    begin 
   
   if (drload) 
        out = in; 
    end 
endmodule



module enaltrom (
address , // Address input
data     // Data output

);
input [3:0] address;
output [16:0] data;


reg [16:0] data ;
       
always @ (  address)
begin
  case (address)
    0 : data = 17'b01000000001000001;
    1 : data = 17'b11001010010010;
    2 : data = 17'b11000000000100000;
    3 : data = 0;
    4 : data = 0;
    5 : data = 0;
    6 : data = 0;
    7 : data =0;
    8 : data = 17'b1000010011001;
    9 : data = 17'b100000100000;
    10 : data = 17'b1000010011011;
    11 : data =17'b100100100000;
    12 : data = 17'b100000000100000;
    13 : data = 8'h90;
    14 : data = 17'b10000000000;
    15 : data = 0;
  endcase
end

endmodule




module ir_register (out, in, irload, clk);
  parameter n = 2;

  output [n-1:0] out;
  input [n-1:0] in;
  input irload;
  input clk;

  reg [n-1:0] out;

  always @(posedge clk) 
    begin 
      if (irload) 
        out = in; 
    end 
endmodule 




module mux (a, b, s, o);
input   [3:0]     a,b;
input   s;
output   [3:0]    o;
reg       [3:0]   o;
always @(a or b   or s)
begin
   if (s == 1'b0)
      o = a;
   else if (s == 1'b1)
      o = b;

end
endmodule



module pc_register (out, in, pcload,  pcinc,clk);
  parameter n = 6;

  output [n-1:0] out;
  input [n-1:0] in;
  input pcload;
  input clk;
  input pcinc;
  

  reg [n-1:0] out;

  always @(posedge clk) 
    begin 
      if (pcinc)
            out = out + 5'h1;
        else if(pcload) 
        out = in; 
    end 
endmodule 




module dflipflop (
data   , // Data Input
clk    , // Clock Input
// Reset input
q        // Q output
);
//-----------Input Ports---------------
input data, clk ; 

//-----------Output Ports---------------
output q;

//------------Internal Variables--------
reg q;

//-------------Code Starts Here---------
always @ ( posedge clk)
 begin
  q <= data;
end

endmodule //End Of Module dff_sync_reset


module main_rom(

address , // Address input
data     // Data output

);
input [5:0] address;
output [7:0] data; 

           
reg [7:0] mem [0:63] ;  
      
assign data = mem[address] ;

initial begin
  $readmemb("memory.list", mem); // memory_list is memory file
end
endmodule

Solution

  • To debug Verilog code problems, you need to create testbench stimulus code and run simulations.

    The diagrams you linked to are too difficult to read. Since you didn't provide any of the submodules, no one can compile your code. You didn't describe what output you are getting and how it differs from what you expect.

    Break your problem down into smaller pieces and start debugging each individually.