Resource Sharing

SungchulCHA·2024년 6월 27일

Verilog

목록 보기
4/8

Resource Sharing

  • solution
always @(posedge Clk)
begin

  case (Sel)
    2'b00: Data_Out = A + B;
    2'b01: Data_Out = E + F;
    2'b10: Data_Out = G + H;
    2'b11: Data_Out = L + M;
  endcase
end
assign Z = X ? A + B : C + D;
always @(*)
begin
  if (SEL == 1'b1)
    begin
      Op1 = A;
      Op2 = B;
    end
  else
    begin
      Op1 = C;
      Op2 = D;
    end
  
  SUM = Op1 + Op2;
end

Adder resource block을 sharing 함


Adder 다양하게 사용하는 법

  • hdlin_use_carry_in
    • Apply a timing constraint
    • Implement TCL command before executing the Presto Verilog Elaborate command : set hdlin_use_carry_in true
// Alternative Style
input [7:0]  Data_A;
input [7:0]  Data_B;
input        Carryin;
output       Carryout;
output [7:0] Data_Out;

assign {Carryout,Data_Out} = Data_A + Data_B + Carryin;

Serial Addition Inefficiency

Data_Out = Data_A + Data_B + Data_C + Data_D;

resource sharing 안됨. 연속된 연산자는 괄호로 묶기

  • solution
Data_Out = (Data_A + Data_B) + (Data_C + Data_D);

Sum_Out = 0;
for (K = 0; K <= 7; K = K + 1)
  begin
    Sum_Out = Sum_Out + A[K];
  end
  • solution 1
always @(A)
begin

  Temp_1 = A[0] + A[1];
  Temp_2 = A[2] + A[3];
  Temp_3 = A[4] + A[5];
  Temp_4 = A[6] + A[7];
  Temp_5 = Temp_1 + Temp_2;
  Temp_6 = Temp_3 + Temp_4;
  Sum_Out = Temp_5 _ Temp_6;
  
end
  • solution 2
always @(A)
begin

  Sum_Out = ((A[0] + A[1])  +
             (A[2] + A[3])) +
            ((A[4] + A[5])  +
             (A[6] + A[7]));
             
end

for loop Resorce Sharing

for loop 안에 연산자 넣으면 resource sharing 안됨

OFFSET[1] = 5'd1;  OFFSET[2] = 5'd2;
OFFSET[3] = 5'd4;  OFFSET[4] = 5'd8;
OFFSET[5] = 5'd16; OFFSET[6] = 5'd17;
OFFSET[7] = 5'd20; OFFSET[8] = 5'd24;

TEMP_OFFSET = 5'd0;

  for (I = 8; I >= 1; I = I - 1)
    if (IRQ[I])
      TEMP_OFFSET = OFFSET[I];
      OFFSET[1] = 5'd1
        OFFSET[1] = 5'd1;
  ADDR = BASE_ADDR + TEMP_OFFSET;

Unnecessary always Statements

// Reg_0 conditionally assigned
always @ (posedge Clock)
begin

  if (Sel == 2'b00)
    begin
      Reg_0 <= Data_In_A + Data_In_B;
    end
    
end

// Reg_1 conditionally assigned
always @ (posedge Clock)
begin

  if (Sel == 2'b01)
    begin
      Reg_1 <= Data_In_A - Data_In_B;
    end
    
end

...

// Reg_3 ocndiionally assigned
always @ (posedge Clock)
begin

  if (Sel == 2'b11)
    begin
      Reg_3 <= Data_In_A + (~ Data_In_B);
    end
    
end

// conditionallly select Reg_N
assign Data-Out = 
    (Sel == 2'b00) ? Reg_0 :
    (Sel == 2'b01) ? Reg_1 :
    (Sel == 2'b10) ? Reg_2 : Reg_3;

같은 연산 반복하지 말자

  • solution
always @ (posedge Clock)
begin

  case (Sel)
    2'b00: Data_Out <= Data_In_A + Data_In_B;
    2'b01: Data_Out <= Data_In_A - Data_In_B;
    2'b10: Data_Out <= Data_In_B - Data_In_A;
    2'b11: Data_Out <= Data_In_A + (~ Data_In_B);
  endcase
end

Unnecessary function Call

AND_Reduced_ALU = &ALU (Input_1, Input_2);
OR_Reduced_ALU = |ALU (Input_1, Input_2);

절대 공유 안됨

  • solution
Temp_Var = ALU(Input_1, Input_2);

AND_Reduced_ALU = &Temp_Var;
OR_Reduced_ALU = |Temp_Var;

if (Sel)
  begin
    Data_out = Big_Function(In_A);
  end
else
  begin
    Data_Out = Big_Function(In_B);
  end
  • solution
if (Sel)
  begin
    Temp_Value = In_A;
  end
else
  begin
    Temp_Value = In_B;
  end

Data_Out = Big_Function(Temp_Value);

Unnecessary Extra Flip-Flops

reg [7:0] Count;

always @ (posedge Clock)
begin
  if (Reset)
    begin
      Count = 8'b0;
    end
  else
    begin
      Count = Count + 1;
    end
    
  And_Bits <= &Count;
  Or_Bits <= |Count;
  Xor_Bits <= ^Count;
end
  • solution
reg [7:0] Count;

always @ (posedge Clock)
begin
  if (Reset)
    begin
      Count = 8'b0;
    end
  else
    begin
      Count = Count + 1;
    end
end

always @(Count)
begin
  And_Bits <= &Count;
  Or_Bits <= |Count;
  Xor_Bits <= ^Count;
end

Unnecessary Repeated Computations

S[0] = A[0] & A[1];
for (K = 1; K <= 7; K = K + 1)
  begin
    if (K > (A - 1))
      begin
        S[K] = 1'b1;
      end
    else
      begin
        S[K] = 1'b0;
      end
  end
  • solution
S[0] = A[0] & A[1];
for (K = 1; K <= 7; K = K + 1)
  begin
    if ((K + 1) > A)
      begin
        S[K] = 1'b1;
      end
    else
      begin
        S[K] = 1'b0;
      end
  end

Duplication of Resources: Trade-off

always @(*)
begin

  Temp_Ptr = (Sel == 1'b1) ? In_Ptr_1 : In_Ptr_2;
  
  Temp_Offset = BASE - Temp_Ptr;
  
  Temp_Addr = In_Address - {8'h00, Temp_Offset};
  
  Out_Count = Temp_Addr + In_Offset_B;
  
end
  • solution : Area는 안좋아지지만 Timing이 좋아짐
always @(*)
begin
  
  Temp_Offset_1 = BASE - Temp_Ptr_1;
  Temp_Offset_2 = BASE - Temp_Ptr_2;
  
  Temp_Addr_1 = In_Address - {8'h00, Temp_Offset_1};
  Temp_Addr_2 = In_Address - {8'h00, Temp_Offset_2};
  
  Temp_count_1 = Temp_Addr_1 + In_Offset_B;
  Temp_count_2 = Temp_Addr_2 + In_Offset_B;
  
  Out_Count = (Sel == 1'b1) ? Temp_Count_1 : Temp_Count_2;
  
end

Variable Part-Select

for (K = 0; K < 64; K = K + 1)
  begin
    FIFO_Mem[(Wr_Ptr * 64) + K] = Data_In[K];
  end

무조건 '='의 왼쪽은 결과, 오른쪽은 연산

  • solution 1
FIFO_Mem[(Wr_Ptr * 64) +:64] = Data_In[63:0]

offset(Wr_Ptr*64)을 기준으로 64개의 bit를 선택

  • solution 2
for (K = 0; K < 64; K = K + 1)
  begin
    Data_out[K] = FIFO_Mem[(Rd_Ptr * 64) + K];
  end
  • solution3 : 제일 좋은거
Data_Out = FIFO_Mem[(Rd_Ptr * 64) +:64];
  • Variable Part-Select

    • implied when the symbol +: or -: occurs in a part-select
    • base index is specified along with a known constant number of bits that are to be extracted
    • Variable base index is always written on the left irrespective of whether the array is declared in an ascending or descending direction
  • example

reg [0:7] Ascending_Array;

...
  Data_Out = Ascending_Array[Index_Var +: 3];

Data_Out이 descending array일 때, ascending array 주는거 불가능
Index_Var = 0 : [0, 1, 2]
Index_Var = 1 : [1, 2, 3]
Index_Var = 3 : [2, 3, 4]
...
Index_Var의 최대값은 5
0에서 7까지 8개의 bit가 있고 3개씩 선택하므로.


reg [0:7] Ascending_Array;

...
  Data_Out = Ascending_Array[Index_Var -: 3];

Index_Var = 2 : [0, 1, 2]
Index_Var = 3 : [1, 2, 3]
Index_Var = 4 : [2, 3, 4]
...
Index_Var의 최소값은 2


reg [7:0] Descending_Array;

...
  Data_Out = Ascending_Array[Index_Var -: 3];

Index_Var = 2 : [2, 1, 0]
Index_Var = 3 : [3, 2, 1]
Index_Var = 4 : [4, 3, 2]
...
Index_Var의 최소값은 2


reg [7:0] Descending_Array;

...
  Data_Out = Ascending_Array[Index_Var +: 3];

Index_Var = 0 : [2, 1, 0]
Index_Var = 1 : [3, 2, 1]
Index_Var = 2 : [4, 3, 2]
...
Index_Var의 최대값은 5

profile
Myongji UNIV. B.S. in Electronic Engineering

0개의 댓글