Businveter:就是IO的輸入輸出的變化會導緻大量的動态功耗,若采用一個inveter位表示一個輸入輸出是否需要翻轉,可以使得IO翻轉大大減少,進而動态功耗也就降低了。具體的操作就是當hanming距離大于bus的bit數加上inveter的位數的變化位數的一半的時候那就翻轉,invetert置為1。Haming距離就是前一個輸出與目前輸出的需要翻轉的個數。
首先是沒有Bus-inveter的verilog:
module Busconveter(
clk,
bus_input,
bus_output
);
input wire clk;
input wire [15:0]bus_input;
output reg [15:0]bus_output;
always@(posedge clk)
bus_output <= bus_input;
endmodule
接着是有Bus-invetert技術的代碼:
module Bus_inveter(
clr,
clk,
bus_input,
bus_output,
inveter
);
input wire clr;
input wire clk;
input wire [15:0]bus_input;
output reg [15:0]bus_output;
output reg inveter;
reg [15:0]temp;
reg [3:0]count;
always@(posedge clk,posedge clr) //如果count(Hamming distance)>Bus_input and pre_output,翻轉
if(clr)
begin
bus_output <= 16'b0;
end
else
begin
if(inveter == 1)
begin
bus_output <= ~bus_input;
end
else
begin
bus_output <= bus_input;
end
end
always@(posedge clk,posedge clr)
if(clr)
begin
count <= 4'b0;
inveter <= 1'b0;
end
else
begin
count = 0;
if((bus_input[0]^temp[0]) == 1'b1)
count = count + 1;
if((bus_input[1]^temp[1]) == 1'b1)
count = count + 1;
if((bus_input[2]^temp[2]) == 1'b1)
count = count + 1;
if((bus_input[3]^temp[3]) == 1'b1)
count = count + 1;
if((bus_input[4]^temp[4]) == 1'b1)
count = count + 1;
if((bus_input[5]^temp[5]) == 1'b1)
count = count + 1;
if((bus_input[6]^temp[6]) == 1'b1)
count = count + 1;
if((bus_input[7]^temp[7]) == 1'b1)
count = count + 1;
if((bus_input[8]^temp[8]) == 1'b1)
count = count + 1;
if((bus_input[9]^temp[9]) == 1'b1)
count = count + 1;
if((bus_input[10]^temp[10]) == 1'b1)
count = count + 1;
if((bus_input[11]^temp[11]) == 1'b1)
count = count + 1;
if((bus_input[12]^temp[12]) == 1'b1)
count = count + 1;
if((bus_input[13]^temp[13]) == 1'b1)
count = count + 1;
if((bus_input[14]^temp[14]) == 1'b1)
count = count + 1;
if((bus_input[15]^temp[15]) == 1'b1)
count = count + 1;
begin
if(count >= 8)
begin
inveter <= 1'b1;
end
else
begin
inveter <= 1'b0;
end
end
end
always@(posedge clk,posedge clr)
if(clr)
temp <= 16'b0;
else
temp <= bus_output;
endmodule
仿真代碼:
module test;
// Inputs
reg clr;
reg clk;
reg [15:0] bus_input;
// Outputs
wire [15:0] bus_output;
wire inveter;
// Instantiate the Unit Under Test (UUT)
Bus_inveter uut (
.clr(clr),
.clk(clk),
.bus_input(bus_input),
.bus_output(bus_output),
.inveter(inveter)
);
always #50 clk = ~clk;
initial begin
$dumpfile("Bus_conveter.vcd");
$dumpvars(1,test.uut);
// Initialize Inputs
bus_input = 0;
clk = 0;
clr = 1;
// Wait 100 ns for global reset to finish
#100;
clr = 0;
bus_input = 16'hffff;
#100;
bus_input = 16'heeee;
#100;
bus_input = 16'h1111;
#100;
bus_input = 16'h1100;
#100;
bus_input = 16'hffec;
#100;
bus_input = 16'h0000;
#100;
bus_input = 16'hedef;
#100;
bus_input = 16'h1234;
#100;
bus_input = 16'h4356;
#100;
bus_input = 16'h7870;
#100;
bus_input = 16'h2e34;
#100;
bus_input = 16'hc311;
#100;
bus_input = 16'h2313;
#100;
bus_input = 16'h2313;
#100;
bus_input = 16'h1111;
#100;
bus_input = 16'hffff;
#100;
bus_input = 16'h2222;
#100;
bus_input = 16'h12de;
#100;
bus_input = 16'hffff;
#100;
bus_input = 16'hf11f;
#100;
bus_input = 16'hf11f;
// Add stimulus here
end
endmodule