天天看點

數字電路設計之低功耗設計方法一:bus總線翻轉

    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

繼續閱讀