Assignment – 8-bit ALU Power Optimization using OpenLane
(open source)
In this assignment, you will design a simple 8-bit Arithmetic Logic
Unit (ALU) in Verilog, add a registered wrapper with a clock-enable
signal, and measure the effect of this optimization on power
consumption using the OpenLane physical design flow.
You will first create the baseline ALU design without clock gating,
simulate it with a Verilog testbench to produce a VCD file showing
switching activity, and run the full OpenLane flow to obtain area,
timing, and power reports.
Next, you will enable clock gating by using the clock-enable signal
in your registers, re-run the simulation and OpenLane flow, and
compare the power results from both versions.
Your submission must include the Verilog source files, OpenLane
configuration, simulation outputs, OpenLane reports, and a short
analysis comparing dynamic, leakage, and total power between
the baseline and optimized designs, explaining the observed
differences.
You will also prepare a short presentation (5–7 minutes)
summarizing your workflow, showing screenshots of your
simulation waveforms, layout, and power reports, and discussing
your findings on how clock gating affected power, area, and timing.
In summary, here are the steps:
1. Run baseline (alu8_reg) simulation + OpenLane.
2. Change config.tcl to use alu8_reg_ce.v.
3. Run optimized version.
4. Compare power reports in runs/ folder.
Sample of ALU Verilog script (you may use other designs as
well)
// 8-bit ALU
// op[2:0] operation codes:
// 000 = ADD
// 001 = SUB
// 010 = AND
// 011 = OR
// 100 = XOR
// 101 = Shift Left Logical by 1
// 110 = Shift Right Logical by 1
// 111 = Set Less Than (signed)
module alu8 (
input [7:0] a, // operand A
input [7:0] b, // operand B
input [2:0] op, // operation selector
output reg [7:0] y,// result
output reg carry, // carry out (for ADD/SUB)
output zero // high if result is zero
);
wire signed [7:0] as = a;
wire signed [7:0] bs = b;
wire [8:0] add9 = {1'b0, a} + {1'b0, b};
wire [8:0] sub9 = {1'b0, a} - {1'b0, b};
always @* begin
carry = 1'b0;
case (op)
3'b000: begin // ADD
y = add9[7:0];
carry = add9[8];
end
3'b001: begin // SUB
y = sub9[7:0];
carry = sub9[8];
end
3'b010: y = a & b; // AND
3'b011: y = a | b; // OR
3'b100: y = a ^ b; // XOR
3'b101: y = a << 1; // Shift Left Logical
3'b110: y = a >> 1; // Shift Right Logical
3'b111: y = (as < bs) ? 8'd1 : 8'd0; // SLT signed
default: y = 8'h00;
endcase
end
assign zero = (y == 8'h00);
endmodule
Sample of Registered Wrapper (Clock Enable)
// Clock-enable register wrapper for 8-bit ALU
module alu8_reg_ce (
input clk,
input en, // clock enable
input [7:0] a,
input [7:0] b,
input [2:0] op,
output reg [7:0] y,
output reg carry,
output reg zero
);
wire [7:0] alu_y;
wire alu_carry;
wire alu_zero;
alu8 u_alu (
.a(a),
.b(b),
.op(op),
.y(alu_y),
.carry(alu_carry),
.zero(alu_zero)
);
always @(posedge clk) begin
if (en) begin
y <= alu_y;
carry <= alu_carry;
zero <= alu_zero;
end
end
endmodule
Sample of Testbench
`timescale 1ns/1ps
module tb;
reg clk;
reg en;
reg [7:0] a, b;
reg [2:0] op;
wire [7:0] y;
wire carry, zero;
// DUT – change module name for baseline/optimized
alu8_reg_ce dut (
.clk(clk),
.en(en),
.a(a),
.b(b),
.op(op),
.y(y),
.carry(carry),
.zero(zero)
);
initial begin
clk = 0;
forever #5 clk = ~clk; // 100 MHz
end
initial begin
$dumpfile("alu.vcd");
$dumpvars(0, tb);
en = 1;
a = 8'h00; b = 8'h00; op = 3'b000;
#10 a = 8'h05; b = 8'h03; op = 3'b000; // ADD
#10 a = 8'h05; b = 8'h03; op = 3'b001; // SUB
#10 a = 8'h0F; b = 8'hF0; op = 3'b010; // AND
#10 en = 0; // disable updates (only for CE version)
#30 en = 1;
#10 op = 3'b011; // OR
#20 $finish;
end
endmodule
Sample of OpenLane Config
set ::env(DESIGN_NAME) alu8_reg
set ::env(VERILOG_FILES) "\
$::env(DESIGN_DIR)/src/alu8.v \
$::env(DESIGN_DIR)/src/alu8_reg.v"
set ::env(CLOCK_PORT) "clk"
set ::env(CLOCK_PERIOD) "10" ;# 100 MHz
(Change alu8_reg.v to alu8_reg_ce.v for optimized run.)