Module 将导线总线传递到模块时,位发生变化

Module 将导线总线传递到模块时,位发生变化,module,simulation,verilog,processor,Module,Simulation,Verilog,Processor,我在Verilog中模拟一个MIPS处理器,我遇到了一个最奇怪的问题。当我将指令(32位总线)传递到主模块时,它会以某种方式发生变化。例如,当我将指令设置为001000000000100000000001时,在模块内部,我将指令打印为001010011111010000000000000000001,这显然是不同的。没有内部模块直接与内部指令交互,因为它只是被分解成不同的其他部分。通过将总线传递到模块,是什么导致位发生变化 以下是主处理器代码和测试台: module SingleCyclePr

我在Verilog中模拟一个MIPS处理器,我遇到了一个最奇怪的问题。当我将指令(32位总线)传递到主模块时,它会以某种方式发生变化。例如,当我将指令设置为001000000000100000000001时,在模块内部,我将指令打印为001010011111010000000000000000001,这显然是不同的。没有内部模块直接与内部指令交互,因为它只是被分解成不同的其他部分。通过将总线传递到模块,是什么导致位发生变化

以下是主处理器代码和测试台:

 module SingleCycleProc(clk, instruction);
// input    Reset_L, clk;
// input [31:0] startPC;
// output [31:0] dmemOut;
// reg [31:0] dmemOut;

input clk;
input [31:0] instruction;

//Fetch instruction and get new program counter
//wire [31:0] instruction, PC_out;
//reg [31:0] PC;
//InstrMem(PC, instruction);
wire [31:0] sign_extended;

//ProgramCounter(PC, PC_out, zero, sign_extended);


//Break up instruction into basic components
reg [5:0] opcode;
reg [5:0] funct;
reg [15:0] immediate;
reg [25:0] address;

reg [4:0] RSAddr, RTAddr, RDAddr;
wire [31:0] RSData, RTData, RDData;


SIGN_EXTEND(immediate, sign_extended);

//Generate CPU and ALU control bits
wire regDST, ALUSrc, memToReg, regWrite, memRead, memWrite, branch;
wire [1:0] ALUOp;
CPU_Control_unit(opcode, regDST, ALUSrc, memToReg, regWrite, memRead, memWrite, branch, ALUOp);

wire [3:0] alu_control;
ALU_Control_Unit(alu_control, funct, ALUOp);

//Generate the input addresses to the regfile, and retrieve data from regfile
wire [4:0] out;
MUX5_2to1(RTAddr, RDAddr, regDST, out);


RegFile(RSData, RTData, RSAddr, RTAddr, RDData, RDAddr, regWrite, clk);

//select intputs to the ALU and do calculation
wire [31:0] alu_in1;
MUX32_2to1(RTData, sign_extended, ALUSrc, alu_in1);

wire [31:0] alu_out;
wire overflow, cin, cout, zero, PCSrc;
wire [31:0] result;
and(PCSrc, branch, zero);
ALU_behav(RSData, alu_in1, alu_control, result, overflow, cin, cout, zero);

wire [31:0] memReadData;
DataMem(result, clk, memRead, memWrite, RTData, memReadData);
MUX32_2to1(result, memReadData, memToReg, RDData);

always @(negedge clk) begin
    // assign PC = PC + 4;
    assign opcode = instruction[31:26];
    assign funct = instruction[5:0];
    assign immediate = instruction[15:0];
    assign address = instruction[25:0];
    assign RSAddr = instruction[25:21];
    assign RTAddr = instruction[20:16];
    assign RDAddr = instruction[15:11];
    // assign dmemOut = RDData;
end

// always @(~Reset_L) assign PC = startPC;

//Monitor changes in the program counter
// always @(PC)
    // #10 $display($time," PC=%d Instr: op=%d rs=%d rt=%d rd=%d imm16=%d funct=%d",
    // PC,instruction[31:26],instruction[25:21],instruction[20:16],instruction[15:11],instruction[15:0],instruction[5:0]);



//Monitors memory writes
always @(clk)
    begin
        #1 $display($time, " clk=%b instruction=%b", clk, instruction);
    // #1 $display($time " clk=%b opcode=%b", clk, opcode);
    // #1 $display($time,
        // " clock=%b RSAddr=%d RSData=%d RTAddr=%d RTData=%d",
        // clk,        RSAddr,   RSData,   RTAddr,   RTData);
    // #1 $display($time, " clk=%b regDST=%b regWrite=%b ALUSrc=%b memRead=%b memWrite=%b memToReg=%b branch=%b ALUOp=%b ", clk, regDST, regWrite, ALUSrc, memRead, memWrite, memToReg, branch, ALUOp);
end

endmodule

module testCPU(clk, Reset_L, startPC, testData);
input clk;
input [31:0] testData;
output Reset_L;
output [31:0] startPC;
reg  Reset_L;
reg [31:0] startPC;

reg [31:0] instruction;
SingleCycleProc(clk, instruction);

initial begin
    // Your program 1
    // Reset_L = 0;  startPC = 0 * 4;
    // #101 // insures reset is asserted across negative clock edge
    // Reset_L = 1;
    // #10000; // allow enough time for program 1 to run to completion
    // Reset_L = 0;
    // #1 $display("Program 1: Result: %d", testData);

    //addi $8, $0, 1
    instruction = 00100000000010000000000000000001;
    #100
    //add $8, $8, $8
    instruction = 00000001000010000100000000100000;
    #100


  $finish;
end
endmodule // testCPU

module TopProcessor;
wire reset, clk, Reset_L;
wire [31:0] startPC;
wire [31:0] testData;

m555 system_clock(clk);
testCPU(clk, Reset_L, startPC, testData);
//SingleCycleProc SSProc(clk, Reset_L, startPC, testData);


endmodule // TopProcessor

您没有告诉Verilog指令是一个二进制数,因此它将其解释为十进制数。你需要这个:

instruction = 32'b00100000000010000000000000000001;
#100
//add $8, $8, $8
instruction = 32'b00000001000010000100000000100000;

此外,您不应该将
assign
语句放在
始终
块中。如果您希望这些是寄存器,请使用verilog非阻塞赋值运算符
您没有告诉verilog指令是二进制数,因此它将其解释为十进制数。你需要这个:

instruction = 32'b00100000000010000000000000000001;
#100
//add $8, $8, $8
instruction = 32'b00000001000010000100000000100000;

此外,您不应该将
assign
语句放在
始终
块中。如果您希望这些是寄存器,请使用verilog非阻塞赋值运算符
您没有告诉verilog指令是二进制数,因此它将其解释为十进制数。你需要这个:

instruction = 32'b00100000000010000000000000000001;
#100
//add $8, $8, $8
instruction = 32'b00000001000010000100000000100000;

此外,您不应该将
assign
语句放在
始终
块中。如果您希望这些是寄存器,请使用verilog非阻塞赋值运算符
您没有告诉verilog指令是二进制数,因此它将其解释为十进制数。你需要这个:

instruction = 32'b00100000000010000000000000000001;
#100
//add $8, $8, $8
instruction = 32'b00000001000010000100000000100000;

此外,您不应该将
assign
语句放在
始终
块中。如果您希望这些是寄存器,请使用verilog non blocking assignment运算符
过多注释,您可以清理代码并再次粘贴吗?读者会更容易阅读过多注释,您可以清理代码并再次粘贴吗?读者会更容易阅读过多注释,你能清理你的代码并再次粘贴吗?这对读者来说会更容易。注释太多了,你能清理你的代码并再次粘贴吗?这对读者来说会更容易