Module 将导线总线传递到模块时,位发生变化
我在Verilog中模拟一个MIPS处理器,我遇到了一个最奇怪的问题。当我将指令(32位总线)传递到主模块时,它会以某种方式发生变化。例如,当我将指令设置为001000000000100000000001时,在模块内部,我将指令打印为001010011111010000000000000000001,这显然是不同的。没有内部模块直接与内部指令交互,因为它只是被分解成不同的其他部分。通过将总线传递到模块,是什么导致位发生变化 以下是主处理器代码和测试台:Module 将导线总线传递到模块时,位发生变化,module,simulation,verilog,processor,Module,Simulation,Verilog,Processor,我在Verilog中模拟一个MIPS处理器,我遇到了一个最奇怪的问题。当我将指令(32位总线)传递到主模块时,它会以某种方式发生变化。例如,当我将指令设置为001000000000100000000001时,在模块内部,我将指令打印为001010011111010000000000000000001,这显然是不同的。没有内部模块直接与内部指令交互,因为它只是被分解成不同的其他部分。通过将总线传递到模块,是什么导致位发生变化 以下是主处理器代码和测试台: module SingleCyclePr
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运算符过多注释,您可以清理代码并再次粘贴吗?读者会更容易阅读过多注释,您可以清理代码并再次粘贴吗?读者会更容易阅读过多注释,你能清理你的代码并再次粘贴吗?这对读者来说会更容易。注释太多了,你能清理你的代码并再次粘贴吗?这对读者来说会更容易