I have implemented a BCD converter on which I worked from two different PCs:
- A computer (AMD Ryzen 7 3700X 8-Core processor, GeForce RTX 2070 SUPER, 32GB ram – Windows 10)
- A laptop (Intel i7-1165G7 processor, 32GB ram – Windows 11 PRO)
As an IDE, I used Vivado 2024.2 for both computers and a Basys3 development board for implementation.
Upon running a behavioral simulation on the BCD (same code for both PCs), on the computer, whatever I do, the output stays at X, but on the laptop the output changes correctly, according to the implemented design. For both PCs, from synthesis onward, the results are the same and the program works correctly after generating the bitstream and loading the program onto the board.
For completions sake, I will also include the code of the design:
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
My question is why does this happen? Is it a problem between the two differing operating systems, but, if so, why does it only affect simulation and not synthesis?