奇技淫巧我不会,但我这有一些我工作后才学到的一些Verilog写法。
assign或always@(*)
always@(posedge clk or negedge rst_n)
always @(*)begin
casez(code)
8'b1???_???? : data[2:0] = 3'd7;
8'b01??_???? : data[2:0] = 3'd6;
8'b001?_???? : data[2:0] = 3'd5;
8'b0001_???? : data[2:0] = 3'd4;
8'b0000_1??? : data[2:0] = 3'd3;
8'b0000_01?? : data[2:0] = 3'd2;
8'b0000_001? : data[2:0] = 3'd1;
8'b0000_0001 : data[2:0] = 3'd0;
default : data[2:0] = 3'd0;
endcase
end
这样的case有优先级选择,可综合,实际项目可以使用,不过我个人习惯上还是,有优先用if-else,没有直接用case。synopsys的EDA工具有关于full case与parallel case可以查看下面博客链接。https://blog.csdn.net/li_hu/article/details/10336511 generate
genvar i;
for(i=0;i<16;i=i+1)
begin: neg_data
assign neg_data_out[i*DATA_WIDTH +:DATA_WIDTH] =
-data_in[i*DATA_WIDTH +:DATA_WIDTH]
end
endgenerate
generate
genvar i;
0;i<16;i=i+1) =
begin: mult_12x12
DW02_mult #(
.A_WIDTH(12),
.B_WIDTH(12)
u_DW02_mult0(
+:12]),
+:12]),
.TC(1'b0),
+:24])
);
end
endgenerate
generate if(MUX_NUM == 0)begin : mux4_1
always@(*)begin
case(sel[1:0])
2'b00:data_out = data_in0;
2'b01:data_out = data_in1;
2'b10:data_out = data_in2;
default:data_out = data_in3;
endcase
end
end else if(MUX_NUM = 1) begin : mux3_1
always@(*)begin
case(sel[1:0])
2'b00:data_out = data_in0;
2'b01:data_out = data_in1;
default:data_out = data_in2;
endcase
end
end else begin : mux2_1
always@(*)begin
case(sel[1:0])
2'b00:data_out = data_in0;
default:data_out = data_in1;
endcase
end
end endgenerate
generate
case(MUX_NUM)
0:begin:mux_2
end
1:begin: mux_3
end
2:begin: mux_4
end
default:begin
end
endcase
end endgenerate
mux #(
.MUX_NUM(0)
)
u_mux(
...
);
always @(*)begin
case(sel)
CASE0:data_out = data_in0;
CASE1:data_out = data_in1;
CASE2。。。
default:;
endcase
end
mux #(
.CASE0(8'd11),
.CASE1(8'd44)
...
)
u_mux(
...
);
assign data_shift[6:0] = data[4:0] << 2;
assign data_shift[7:0] = data[4:0] << shift[1:0];
assign data_shift[6:0] = {data[4:0], 2'b0};
always @(*)begin
case(shift[1:0])
2'b00: data_shift[7:0] = {3'b0, data[4:0]};
2'b01: data_shift[7:0] = {2'b0, data[4:0], 1'b0};
2'b10: data_shift[7:0] = {1'b0, data[4:0], 2'b0};
default:data_shift[7:0] = {data[4:0], 3'b0};
endcase
end
always @(*)begin
case(shift[1:0])
2'b00: data_shift[7:0] = {{3{data[4]}}, data[4:0]};
2'b01: data_shift[7:0] = {{2{data[4]}}, data[4:0], 1'b0};
2'b10: data_shift[7:0] = {data[4], data[4:0], 2'b0};
default:data_shift[7:0] = {data[4:0], 3'b0};
endcase
end
parameter DATA_WIDTH = 4,
parameter CNT_WIDTH = log2(DATA_WIDTH)
parameter CNT_WIDTH = clog2(DATA_WIDTH-1)
parameter CNT_WIDTH = $clog2(DATA_WIDTH)
reg [DATA_WIDTH-1:0] data_r0;
reg [CNT_WIDTH-1:0] cnt;
//-------------------------------------------------------
//以下两个函数任用一个
//求2的对数函数
function integer log2;
input integer value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
//求2的对数函数
function integer clogb2 (input integer bit_depth);
begin
for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
bit_depth = bit_depth>>1;
end
endfunction
assign signal_b = signal_a;
assign data_b = data_a;
assign cs_en = 1'b1;
assign signal_b = signal_a;
assign data_b = data_a;
assign cs_en = 1'b1;
给模块起名字,给信号起名字,真的很难,但是不管怎样都不要用拼音,会遭人鄙视。是的,我见过!
assign data_out[5:0] = data_vld0 ? data0[5:0] :
data_vld1 ? data1[5:0] :
data_vld2 ? data2[5:0] :
data_vld3 ? data3[5:0] : 6'b0;
assign data_out[5:0] = ({6{data_vld0}} & data0[5:0])
| ({6{data_vld1}} & data1[5:0])
| ({6{data_vld2}} & data2[5:0])
| ({6{data_vld0}} & data3[5:0]);
reg [10000-1:0] data;
这样写在功能上没什么问题,但是如果你之后有对这个数据做了很多逻辑,可能会造成后端布线太密,从后端的角度看到其实cell数量并不多,就是线比较密,比如说这个数据后面再放个选择器,或者输出给其他模块,就相当于一万根线连到很多地方,布线很紧张,如果时序有问题需要绕线,或者需要ECO,做成的可能性很小。
尽量不要这样做逻辑,除非对面积没限制,要么最后只能改架构。
第二个原因是负载太大。同一个信号在很多地方使用,布线也会变复杂,比如最常见的是参数信号,在很多模块都会有用到的情况,用寄存器复制的方法。always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_para0 <= 4'b0;
data_para1 <= 4'b0;
data_para2 <= 4'b0;
end
else begin
data_para0 <= data_para;
data_para1 <= data_para;
data_para2 <= data_para;
end
end
有网友提到这样子写被综合掉的概率也是很大。所以就只能在设计时尽量注意负载的问题。
assign sum[4:0] = enable ? (data_a + data_b) : (data_c + data_d);
assign add_a[3:0] = enable ? data_a : data_c;
assign add_b[3:0] = enable ? data_b : data_d;
assign sum[4:0] = add_a + add_b;
画个图意思一下。
审核编辑 :李倩
全部0条评论
快来发表一下你的评论吧 !