How can I assign a "don't care" value to an output in a combinational module in Verilog -
How can I assign a "don't care" value to an output in a combinational module in Verilog -
imagine want describe combinational circuit satisfy next truth table:
a b | s0 s1 s2 s3 ----------------- 0 0 | 1 d d d 0 1 | 0 1 d d 1 0 | 0 0 1 d 1 1 | 0 0 0 1
(where d
stands "don't care" value, is, don't care if value of output 0 or 1)
if go through traditional design, can take advantage of these "don't cares" , assign them convenient values resulting equations (and hence, circuit) simple ones. example, alter previous truth table one:
a b | s0 s1 s2 s3 ----------------- 0 0 | 1 1 1 1 0 1 | 0 1 0 1 1 0 | 0 0 1 1 1 1 | 0 0 0 1
and final equations (using verilog notation):
s0 = ~a & ~b; s1 = ~a; s2 = ~b; s3 = 1;
(remember when had take values outputs in k-map grouping much cells can)
but if take design using verilog? cannot this:
module encoder ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b1ddd; 2'b01 : s = 4'b01dd; 2'b10 : s = 4'b001d; 2'b11 : s = 4'b0001; default: s = 4'bdddd; endcase end endmodule
i told @ how assign default values outputs in combinational block... couldn't utilize x
output either, input. , if utilize z
, resulting circuit worse in terms of complexity , resources used, tristate buffers needed.
so i'm forced take @ design time values (1
or 0
) want output, , these values don't have yield optimized circuit:
module encoder ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b1000; 2'b01 : s = 4'b0100; 2'b10 : s = 4'b0010; 2'b11 : s = 4'b0001; default: s = 4'b0000; endcase end endmodule
which leads these equations (ignoring default
clause moment):
s0 = ~a & ~b; s1 = ~a & b; s2 = & ~b; s3 = & b;
or implementation (taken output of yosis 0.3.0 @ edaplayground):
which may or may not best solution given target, allow synthesizer infer given outputs want.
using xst synthesizer targetting spartan 3e-100k fpga, above module uses 2 slices , 4 luts.
i assume verilog (or other hdl) should free designer having such choices, synthesizer can apply whatever optimizations available if designer allows take convenient value given output , given set of inputs. if case, previous design have been optimized this:
targetting same fpga above, uses 2 slices , 3 luts.
for example, i've been able create optimizations hand, consider controller module dozen of outputs datapath module. there output signals controller may have don't care value given state of controller.
for example: controller outputs signal select
register or register b, , signal enable load
of register c, register c can loaded either or b, or maintain current value.
if load
0, don't care value of select
, everytime in controller description output load = 0
, should able output "don't care" select
.
so questions are:
is there way write verilog (not systemverilog) description can give "don't care values" outputs combinational blocks?
if not, limitation in language, or much matter of "you should create designs 'don't care' values not needed"?
addendum
to surprise, xst recognizes `x` valid output. it's synthesizable and seems behave way expected, resulting in same circuit implemented 2 slices , 3 luts. yosis, on other way, seems ignore , produces same output non optimized design.
rectification: i've tested xst design: circuit produces truth table:
a b | s0 s1 s2 s3 ----------------- 0 0 | 0 d d d 0 1 | 1 0 d d 1 0 | 1 1 0 d 1 1 | 1 1 1 0
the corresponding verilog module, written without don't cares, written in number of ways, example, one:
module encoder ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b0111; 2'b01 : s = 4'b1011; 2'b10 : s = 4'b1101; 2'b11 : s = 4'b1110; default: s = 4'b1111; endcase end endmodule
which produces worst result, in terms of minimization (2 slices, 4 luts in spartan 3e fpga)
an optimized hand version can obtained starting truth table:
a b | s0 s1 s2 s3 ----------------- 0 0 | 0 0 0 0 0 1 | 1 0 1 0 1 0 | 1 1 0 0 1 1 | 1 1 1 0
it's easy observe here 3 4 outputs can obtained without single logic gate. thus, xst reports 1 slice, 1 lut (the 1 needed calculate s0)
module encoder ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b0000; 2'b01 : s = 4'b1010; 2'b10 : s = 4'b1100; 2'b11 : s = 4'b1110; default: s = 4'b1110; // yes, same output above endcase end endmodule
if utilize dirty trick of using x
"don't care":
module encoder ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b0xxx; 2'b01 : s = 4'b10xx; 2'b10 : s = 4'b110x; 2'b11 : s = 4'b1110; default: s = 4'bxxxx; endcase end endmodule
the design synthesizes, result not minimal. xst reports 1 slice, 2 luts.
the paper @tim links in comment clear matter: avoid using x
in designs. according example, language not allow help synthesizer minimize circuit.
saving 1 or 2 luts may not great deal, if savings allow module remain within slice, p&r have less work place wherever wants.
when utilize quartus ii ver 15.0, assiging "don't care" output ok , generated area-efficient circuit.
for example, if synthesize code, :
module test1 ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b1000; 2'b01 : s = 4'b0100; 2'b10 : s = 4'b0010; 2'b11 : s = 4'b0001; default: s = 4'b0000; endcase end endmodule
quartus generated circuit uses 5 logic elements.
however, if utilize "don't care" assignment in code above:
module test1 ( input wire a, input wire b, output reg [3:0] s ); @* begin case ({a,b}) 2'b00 : s = 4'b1xxx; 2'b01 : s = 4'b01xx; 2'b10 : s = 4'b001x; 2'b11 : s = 4'b0001; default: s = 4'b0000; endcase end endmodule
a circuit uses 2 logic elements generated. it's interesting although total logic elements less used, generated circuit seems more complex.
i wondering whether generated circuit correct. ran quartus's simulator circuit uses "don't care". result simplest circuit want.
verilog
Comments
Post a Comment