我已经实现了一个 BCD 转换器,可以在两台不同的 PC 上工作:
- 一台电脑(AMD Ryzen 7 3700X 8 核处理器、GeForce RTX 2070 SUPER、32GB 内存 - Windows 10)
- 一台笔记本电脑(英特尔 i7-1165G7 处理器,32GB 内存 - Windows 11 PRO)
作为 IDE,我在两台计算机上都使用了 Vivado 2024.2,并使用了 Basys3 开发板进行实现。
在 BCD 上运行行为模拟(两台 PC 的代码相同)后,无论我在计算机上做什么,输出都保持在 X,但在笔记本电脑上,输出会根据实施的设计正确更改。对于两台 PC,从综合开始,结果都是相同的,并且在生成比特流并将程序加载到板上后,程序可以正常工作。
为了完整起见,我还将包括设计的代码:
module counter #(parameter SIZE = 4) (
input clk,
input rst,
input en,
output reg [SIZE-1:0] out
);
always @(posedge clk, negedge rst) begin
if(!rst)
out <= 0;
else
if (en) out <= out + 1;
end
endmodule
module loadRegister #(DATA_SIZE = 1, REG_SIZE = 2) (
input clk,
input rst,
input [DATA_SIZE-1:0] Din,
input Sin,
input [REG_SIZE - 1 : 0] cellAdr,
input serialLoad,
input parallelLoad,
output reg [DATA_SIZE * (2 ** REG_SIZE) - 1 : 0] data
);
always @(posedge clk) begin
if(!rst) data <= 0;
else if(parallelLoad) begin
data[DATA_SIZE*cellAdr+:DATA_SIZE] <= Din;
end
else if(serialLoad) begin
data <= {data[DATA_SIZE * (2 ** REG_SIZE) - 2 : 0],Sin};
end
else begin
data <= data;
end
end
endmodule
module Binary2BCDTranscoder #(parameter INPUT_SIZE = 12, parameter OUTPUT_DIGITS = 4, parameter ICNTR_SIZE = 4, parameter JCNTR_SIZE = 2) (
input clk,
input rst,
input convStart,
input [INPUT_SIZE-1:0] data,
output reg convDone,
output reg [4 * OUTPUT_DIGITS - 1:0] convOut
);
localparam WAIT = 2'b00;
localparam CONV_CHK = 2'b01;
localparam FINISHED = 2'b11;
reg iRst, jRst, iEn, jEn;
wire [ICNTR_SIZE-1:0] i;
wire [JCNTR_SIZE-1:0] j;
reg [1:0] state, next_state;
reg [INPUT_SIZE-1:0] inner_in;
reg loadRegRst;
reg [3:0] loadRegDin;
reg loadRegSin;
reg loadRegSerial, loadRegParallel;
reg [1:0] loadRegCellAdr;
wire [4 * OUTPUT_DIGITS - 1:0] inner_out;
always @(posedge clk) begin
if(!rst) state <= WAIT;
else state <= next_state;
end
always @(posedge clk) begin
if(!rst) inner_in <= 0;
else if(state==WAIT) inner_in <= data;
end
always @(posedge clk) begin
if(state==CONV_CHK & convDone) convOut <= inner_out;
end
counter #(.SIZE(ICNTR_SIZE)) iCounter (
.clk(clk),
.rst(iRst),
.en(iEn),
.out(i)
);
counter #(.SIZE(JCNTR_SIZE)) jCounter (
.clk(clk),
.rst(jRst),
.en(jEn),
.out(j)
);
loadRegister #(.DATA_SIZE(4),.REG_SIZE(2)) innerOutReg (
.clk(clk),
.rst(loadRegRst),
.Din(loadRegDin),
.Sin(loadRegSin),
.serialLoad(loadRegSerial),
.parallelLoad(loadRegParallel),
.cellAdr(loadRegCellAdr),
.data(inner_out)
);
always @(*) begin
case(state)
WAIT: begin
convDone = 0;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
next_state = convStart ? CONV_CHK : WAIT;
end
CONV_CHK: begin
if(i == INPUT_SIZE) begin
convDone = 1;
next_state = FINISHED;
iRst = 0;
jRst = 0;
iEn = 0;
jEn = 0;
end
else if(j == OUTPUT_DIGITS-1) begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 0;
iEn = 1;
jEn = 0;
end
else begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 1;
iEn = 0;
jEn = 1;
end
end
FINISHED: begin
next_state = WAIT;
convDone = 1;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
default: begin
next_state = WAIT;
convDone = 0;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
endcase
end
always @(*) begin
case(state)
WAIT: begin
loadRegRst = 0;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
CONV_CHK: begin
loadRegRst = 1;
if (iEn) begin
loadRegDin = 0;
loadRegSin = inner_in[INPUT_SIZE-1-i];
loadRegParallel = 0;
loadRegSerial = 1;
loadRegCellAdr = 0;
end
else if (jEn) begin
if(inner_out[4*j+:4] >= 5) begin
loadRegDin = inner_out[4*j+:4] + 3;
loadRegSin = 0;
loadRegParallel = 1;
loadRegSerial = 0;
loadRegCellAdr = j;
end
else begin
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
end
else begin
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
end
FINISHED: begin
loadRegRst = 1;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
default: begin
loadRegRst = 0;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
endcase
end
endmodule
module Bin2BCDTest();
reg clk, rst, convStart;
reg [11:0] data;
wire convDone;
wire [15:0] convOut;
Binary2BCDTranscoder #(.INPUT_SIZE(12),.OUTPUT_DIGITS(4),.ICNTR_SIZE(4),.JCNTR_SIZE(2)) dut (
.clk(clk),
.rst(rst),
.convStart(convStart),
.data(data),
.convDone(convDone),
.convOut(convOut)
);
initial begin
clk = 0;
forever #5 clk = !clk;
end
initial begin
rst = 0;
convStart = 0;
#10 rst = 1;
#10 data = 1023;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 512;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 3683;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 4091;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 4090;
#10 convStart = 1;
#20 convStart = 0;
#1000;
$stop;
end
endmodule
为什么会发生这种情况?这是两个不同操作系统之间的问题吗?如果是这样,为什么它只影响模拟而不影响综合?