verilog - 如何将 case inside 语句识别为完全涵盖的 case
问题描述
我需要知道我们如何将 case inside 语句识别为完全涵盖的 case 语句。请看下面的例子:
module test();
logic [1:0] sel;
initial begin
sel = 2'b0x; // 2'b0z, 2'b0?
$display("a is %b", sel);
case (sel) inside
2'b00 : $display("caseinside : 2'b00");
2'b01 : $display("caseinside : 2'b01");
2'b1x : $display("caseinside : 2'b1x");
// 2'bxx : $display("caseinside : 2'bxx");
default : $display("caseinside : default");
endcase
casex (sel)
2'b00 : $display("casex : 2'b00");
2'b01 : $display("casex : 2'b01");
2'b1x : $display("casex : 2'b1x"); // 2'b1x => 2'b10, 2'b11
default : $display("casex : default");
endcase
end
endmodule
这里我们有 case inside 和 casex 语句。而且,案例选择器是一个四态变量。我们已经知道这个 casex 语句是一个完全覆盖的语句,因为它涵盖了所有 2'b00、2'b01 和 2'b1x (2'b10, 2'b11) 案例标签 wrt 案例选择器。
但是,case inside 语句并不像一个完全覆盖的语句。因为,对于给定的选择器值“2'b0x”,case inside 语句将达到其默认 case 项。(模拟)
根据系统verilog LRM和一些实验,我们可以将case内部语句的行为表达如下。(需要知道是否正确)
如果 case 选择器的类型是四态,并且在其位串中包含“x”(或“z”或“?”)值,则匹配的 case 标签必须在相应位置具有“x”值。(也必须匹配其他位)
例如:假设选择器值是,
3’b01x
那么匹配的案例标签将是3’b01x
,3’b0xx
,3’bx1x
,3’bxxx
。根据这个,case 选择器可以有 '3'bxxx' 然后 case inside 语句必须有 '3'bxxx' 标签才能使该语句是一个完全覆盖的语句。并且,如果 case inside 语句具有 '3'bxxx' 标签,则它可以匹配通过 case 选择器的任何 3 位值。
在这些实验之后,我们构建了以下算法来检测 case inside 语句是否是全覆盖语句:
【算法】:(我们这里考虑对应的位串)
如果选择器变量/表达式的类型是四态的,
那么,必须有一个大小写标签,其宽度与大小写选择器的宽度匹配,并且它应该只包含“x”(或“z”或“?”)。这种 case inside 语句将被标识为完全覆盖的语句,否则不是。
(如果标签宽度 > 选择器宽度,那么前导位字符应该是 '0'、'x'、'z' 或 '?' 之一)
如果选择器变量/表达式的类型是二态的,
那么我们可以使用casex现有的算法。(例如:如果 case 选择器的宽度为 2,则 case inside 语句应该有 '00'、'01'、'10' 和 '11' 标签('x'、'z'、'?' 将被扩展根据 2wild_card_count 机制为“0”和“1”))
请让我知道这个算法是否合适,或者我应该继续使用另一种方法(请建议你的算法)。
[* 注意:'default' 子句不应出现在完全涵盖的语句中。成为一个完全涵盖的案例的目的是切断“默认”条款*]
解决方案
我想你正在创建一个编译器 linter 或类似的东西。
我想你有足够小的宽度来扩展每个标签保留一组
const din = document.getElementById('din')
const ul = document.getElementById('expansion');
function refresh(e){
while(ul.lastChild){
ul.removeChild(ul.lastChild);
}
function append(prefix){
const li = document.createElement('li')
li.textContent = prefix;
ul.appendChild(li);
}
const s = din.value;
if(!s) return;
const expandedBits = {
'0': ['0'],
'1': ['1'],
'x': ['0', '1', 'x', 'z'],
'z': ['0', '1', 'x', 'z'],
'?': ['0', '1', 'x', 'z'],
};
for(let i = 0; i < s.length; ++i){
if(!expandedBits[s[i]]){
append('Invalid character: ' + s[i]);
return;
}
}
// this function will enumerate all entries for one
// label
function expand(prefix, i){
if(i >= s.length){
append(prefix);
}else{
for(const b of expandedBits[s[i]]){
expand(prefix + b, i + 1);
}
}
}
expand(s.length +"'b", 0);
}
din.addEventListener('input', refresh);
din.addEventListener('change', refresh);
refresh();
Label <input type="text" id="din" pattern="[xz?01]*" value="11x0010?0">
<ul id="expansion"></ul>
一旦你用这个过程扩展了每个标签,你应该已经产生了所有的4**n
可能性,这有意义吗?
推荐阅读
- python - 基于 Django 模型内部方法的计算字段
- api - 从主机中删除包裹并永久删除包裹的cm-api是什么
- java - 将 java 入口点设置为另一个 JAR 中的 JAR 中的类
- java - 如何在 Apache POI Word 中添加对图片的交叉引用?
- javascript - 即使在javascript对象打印值之后,来自ag-grid的Grid API的“setRowData”方法也不会加载任何行
- windows-installer - 如何 CI-CD 一个 Windows 安装程序?我希望部署将 .msi 放置在特定位置
- reactjs - Reactjs 中的 Downshift - 菜单下拉菜单仅显示所选项目
- javascript - jquery函数“不是函数”在同一个函数冲突中?
- python - 删除列中具有特定值的行
- javascript - 在这个例子中,如何使用 JaveScript 来模仿自定义过滤器/选择器?