当模块为变量赋值时,它显示xxxxxxxx

时间:2016-03-10 09:10:43

标签: verilog

我正在尝试实现一个迷你CPU,但是当我尝试为寄存器2分配值时遇到了麻烦。这里是代码

module miniCPU(
    input [11:0] In,
    input Clock,
    output [7:0] Out,
    output Overflow,
    output [7:0] Re1,
     output [7:0] Re2,
     output cl,
     output ee1,
     output ee2,
     output ee3,
     reg [7:0] tempY,
     input clk,
     input clr
    );

     wire [7:0] r1;
     wire [7:0] r2;
    wire [7:0] y1;
     wire [3:0] y2;
     wire [7:0] Rout;
     wire CLR;
     wire EN1;
     wire EN2;
     wire EN3;
     wire S0;
     wire [2:0] Sel;

    BusSplit B(.i(In[11:0]),.y_1(y1[7:0]),.y_2(y2[3:0]));
     InstructionDecoder I(.Y2(y2[3:0]),.C(CLR),.E1(EN1),.E2(EN2),.E3(EN3),.S(S0),.sel(Sel[2:0]));
     assign cl=CLR;
     assign ee1=EN1;
     assign ee2=EN2;
     assign ee3=EN3;
     assign clk=Clock;
     assign clr=CLR;
     Reg8bit R1(.r(r1[7:0]),.y(y1[7:0]),.CLK(Clock),.clr(CLR),.en(EN1));
     always@(S0)
       if (S0 == 1'b1)
          assign tempY=y1;
        else
          assign tempY=Out;
     Reg8bit R2(.r(r2[7:0]),.y(tempY[7:0]),.CLK(Clock),.clr(CLR),.en(EN2));
endmodule
module BusSplit (i,y_1,y_2);
    input [11:0] i;
     output [7:0] y_1;
     output [3:0] y_2;
    assign y_1 = i[7:0];
    assign y_2 = i[11:8];
endmodule 
module InstructionDecoder (Y2,C,E1,E2,E3,S,sel);
    input [3:0] Y2;

     output  C;
     output  E1,E2,E3,S;     
     output  [2:0] sel;

     reg clr,e1,e2,e3,s;
     reg[2:0] se;
    always@(Y2)
     if (Y2 == 4'b0000)
     begin
        clr=1'b1;
        e1=1'b1;
        e2=1'b1;
        e3=1'b1;

     end
     else if (Y2 == 4'b0001)
     begin
       clr=1'b0;
        e1=1'b1;
        e2=1'b0;
        e3=1'b0;
    end
    else if (Y2 == 4'b0010)
    begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b1;
        e3=1'b0;
        s=1'b0;
    end
    else if (Y2 == 4'b0011)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b1;
        e3=1'b0;
        s=1'b1;
      end
    else if (Y2 == 4'b0100)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b000;
              end
    else if (Y2 == 4'b0101)
     begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b001;
      end
    else if (Y2 == 4'b0110)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b010;
      end
    else if (Y2 == 4'b0111)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b011;
      end
    else if (Y2 == 4'b1000)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b100;
      end
    else if (Y2 == 4'b1001)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b101;
      end
    else
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b0;
      end
      assign C=clr;
      assign E1=e1;
      assign E2=e2;
      assign E3=e3;
      assign S=s;
      assign sel=se;
endmodule
module Reg8bit (r,y,CLK,clr,en);
     input [7:0] y;
     input CLK;
     input clr;
     input en;
     output [7:0] r;
     reg[7:0] tempQ;

  always @(posedge CLK)
  begin
    if (en)
    begin
      if (clr)
        tempQ = 8'b00000000;
      else
        tempQ = y;
    end
  end
  assign r=tempQ;  
endmodule

另一个模块看起来工作正常,当我第一次调用模块Reg8bit时,我将值赋给r1,它可以工作。但是当我第二次调用模块Reg8bit时,r2的值变为xxxxxxxx。它是如此有线,因为模块是相同的,我没有改变任何东西,有人可以帮助我,非常感谢你

1 个答案:

答案 0 :(得分:1)

我修改了你的代码,我认为这应该可以帮助你使代码工作,请参阅代码中的注释:

module miniCPU(
     input  [11:0]In,
     input        Clock,
     output [7:0] Out,
     output       Overflow,
     output [7:0] Re1,
     output [7:0] Re2,
     output       cl,
     output       ee1,
     output       ee2,
     output       ee3,
     //reg [7:0] tempY, //Without direction(in/output). Should not be in the interface or directed. 
     //As it seems to be a temporary value, I will consider that it is an internal signal.
     input        clk,
     input        clr
    );

     wire [7:0] r1;
     wire [7:0] r2;
     wire [7:0] y1;
     wire [3:0] y2;
     wire [7:0] Rout;
     wire CLR;
     wire EN1;
     wire EN2;
     wire EN3;
     wire S0;
     wire [2:0] Sel;

     reg [7:0] tempY; //temporary Y declared here

    //You are not coding software, declaration of the modules have no importance as long as all signals are declared.
    //In my opinion though, it is easier to read a code where all modules declarations are grouped.

     BusSplit B(.i(In[11:0]), .y_1(y1[7:0]), .y_2(y2[3:0]));
     InstructionDecoder I(.Y2(y2[3:0]), .C(CLR), .E1(EN1), .E2(EN2), .E3(EN3), .S(S0), .sel(Sel[2:0]));
     Reg8bit R1(.r(r1[7:0]), .y(y1[7:0]),    .CLK(Clock), .clr(CLR), .en(EN1));
     Reg8bit R2(.r(r2[7:0]), .y(tempY[7:0]), .CLK(Clock), .clr(CLR), .en(EN2));
     assign cl=CLR;

     //Also a personal consideration, but I would put first processes, then output assignements.

     always@(S0 or y1 or Out)//Piece of advice, use always@(*) for combinatorial processes. It will avoid a lot of problem caused by sensitivity lists
       if (S0 == 1'b1)
          //assign tempY=y1;//You cannot 'assign' in process
          tempY = y1;
        else
          //assign tempY=Out;//Same as the previous assignement
          //I am not quite sure of what you want to do here, 'Out' is never assigned --> X in tempY.
          tempY = Out//?


     assign ee1=EN1;
     assign ee2=EN2;
     assign ee3=EN3;
     assign clk=Clock;
     assign clr=CLR;
     assign Out = 8'hXX//Can't guess what you want to do


endmodule
module BusSplit (i,y_1,y_2);
    input [11:0] i;
     output [7:0] y_1;
     output [3:0] y_2;
    assign y_1 = i[7:0];
    assign y_2 = i[11:8];
endmodule 
module InstructionDecoder (Y2,C,E1,E2,E3,S,sel);
    input [3:0] Y2;

     output  C;
     output  E1,E2,E3,S;     
     output  [2:0] sel;

     reg clr,e1,e2,e3,s;
     reg[2:0] se;
    always@(Y2)//Same remark about always@* as earlier
               //Be careful if you want to synthesize you design, there are some signals that are not assigned in some cases, it will generate latches !
               // A way to avoid that is to assign all values with a default value before the case. The case will modify the relevant signals regarding your selection signal :
   begin//more that one line now, need 'begin-end'
     clr = 1'b0;
     e1  = 1'b0;
     e2  = 1'b0;
     e3  = 1'b0;
     s   = 1'b0;
     se  = 3'b000;
     if (Y2 == 4'b0000)
     begin
        clr=1'b1;
        e1=1'b1;
        e2=1'b1;
        e3=1'b1;

     end
     else if (Y2 == 4'b0001)
     begin
       clr=1'b0;
        e1=1'b1;
        e2=1'b0;
        e3=1'b0;
    end
    else if (Y2 == 4'b0010)
    begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b1;
        e3=1'b0;
        s=1'b0;
    end
    else if (Y2 == 4'b0011)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b1;
        e3=1'b0;
        s=1'b1;
      end
    else if (Y2 == 4'b0100)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b000;
              end
    else if (Y2 == 4'b0101)
     begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b001;
      end
    else if (Y2 == 4'b0110)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b010;
      end
    else if (Y2 == 4'b0111)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b011;
      end
    else if (Y2 == 4'b1000)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b100;
      end
    else if (Y2 == 4'b1001)
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b1;
        se=3'b101;
      end
    else
      begin
       clr=1'b0;
        e1=1'b0;
        e2=1'b0;
        e3=1'b0;
      end
   end//end for the always@(Y2)
      assign C=clr;
      assign E1=e1;
      assign E2=e2;
      assign E3=e3;
      assign S=s;
      assign sel=se;
endmodule
module Reg8bit (r,y,CLK,clr,en);
     input [7:0] y;
     input CLK;
     input clr;
     input en;
     output [7:0] r;
     reg[7:0] tempQ;

  always @(posedge CLK)
  begin
    if (en)
    begin
      if (clr)
        tempQ <= 8'b00000000; //Flops should use non-blocking (<=) assignments, not blocking (=)
      else
        tempQ <= y; //Same as previous flop assignment
    end
  end
  assign r=tempQ;  
endmodule