我有两个 4 位信号,表示 24 小时格式的时钟小时的二进制编码十进制:h1_24h 和 h0_24h,分别表示最高有效数字和最低有效数字。
我需要一个组合逻辑块来生成另外两个 4 位信号 h1_12h 和 h0_12h:如果采用 12 小时格式,则对应小时的二进制编码小数,例如,如果 h1_24h = 4'd1 和 h0_24h = 4'd9 ,则 h1_12h = 4'd0 且 h0_12h = 4'd7,因为 24 小时格式中的 19 对应于 12 小时格式中的 07 (pm)。
我的第一次尝试如下:
always_comb begin
{h1_12h, h0_12h} = {h1_24h, h0_24h}; // identical from 01 am to 12 pm
if (h1_24h == 0 && h0_24h == 0) {h1_12h, h0_12h} = {4'd1, 4'd2}; // 00 -> 12
if (h1_24h == 1 && h0_24h >= 3) {h1_12h, h0_12h} = {4'd0, h0_24h - 2}; // 13-19 -> 01-07
if (h1_24h == 2 && h0_24h <= 1) {h1_12h, h0_12h} = {4'd0, h0_24h + 8}; // 20-21 -> 08-09
if (h1_24h == 2 && h0_24h >= 2) {h1_12h, h0_12h} = {4'd1, h0_24h - 2}; // 22-23 -> 10-11
end
在模拟过程中,它似乎按预期工作,除了当小时为 22 或 23 时,在这些情况下,它分别产生 00 和 01,我检查过,并且语句
if (h1_24h == 2 && h0_24h >= 2) {h1_12h, h0_12h} = {4'd1, h0_24h - 2};
在应该时正确执行,但产生错误的输出并且奇怪地改变分配给其他值的最高有效数字不会改变输出,例如将行更改为 if (h1_24h == 2 && h0_24h >= 2) {h1_12h, h0_12h} = {4'd5, h0_24h - 2};
它仍然会产生 00 和 01。
以防万一我尝试使用串联将单行分配替换为多行上更简单的分配,如下所示:
always_comb begin
// identical from 01 am to 12 pm
h1_12h = h1_24h;
h0_12h = h0_24h;
// 00 -> 12
if (h1_24h == 0 && h0_24h == 0) begin
h1_12h = 4'd1;
h0_12h = 4'd2;
end
// 13-19 -> 01-07
if (h1_24h == 1 && h0_24h >= 3) begin
h1_12h = 4'd0;
h0_12h = h0_24h - 2;
end
// 20-21 -> 08-09
if (h1_24h == 2 && h0_24h <= 1) begin
h1_12h = 4'd0;
h0_12h = h0_24h + 8;
end
// 22-23 -> 10-11
if (h1_24h == 2 && h0_24h >= 2) begin
h1_12h = 4'b1;
h0_12h = h0_24h - 2;
end
end
令人惊讶的是,上面的内容在模拟过程中产生了正确的结果,但我想知道为什么前一个描述与后者相反,为什么不起作用。如果重要的话,我正在使用 Vivado 2023.1。
这是因为h024h-2没有用于串联的位宽。以下代码中的修复解决了问题。
typedef bit[3:0] hrs;
if (h1_24h == 2 && h0_24h >= 2) {h1_12h, h0_12h} = {4'd1, hrs'((h0_24h - 2))};