Examples In Verilog | Advanced Chip Design- Practical
always @(posedge gated_clk) q <= d; endmodule
always @(posedge clk_dst or negedge rst_n) begin if (!rst_n) sync, meta <= 2'b00; else sync, meta <= meta, sig_src; end
// Stage 3: Execute (ALU) always @(posedge clk) begin ID_EX_instr <= IF_ID_instr; ID_EX_pc <= IF_ID_pc; ID_EX_rs1 <= reg_data1; ID_EX_rs2 <= reg_data2; end
Add write buffer, ECC, and bank interleaving. 4. Clock Domain Crossing (CDC) Example: 2-flop synchronizer (single-bit) module sync_single ( input clk_dst, rst_n, input sig_src, output reg sig_dst ); reg meta, sync; Advanced Chip Design- Practical Examples In Verilog
// Stage 1: Instruction Fetch always @(posedge clk or negedge rst_n) begin if (!rst_n) begin pc <= 32'b0; IF_ID_instr <= 32'b0; end else begin pc <= pc_next; IF_ID_instr <= instr_mem_data; IF_ID_pc <= pc; end end
assign sig_dst = sync; endmodule module async_fifo #(DEPTH=8, WIDTH=16) ( input wclk, rclk, wrst_n, rrst_n, input wr_en, rd_en, input [WIDTH-1:0] wdata, output [WIDTH-1:0] rdata, output full, empty ); reg [WIDTH-1:0] mem [0:DEPTH-1]; reg [$clog2(DEPTH):0] wptr, rptr; // Gray coded
wire [3:0] wgray = wptr ^ (wptr >> 1); wire [3:0] rgray = rptr ^ (rptr >> 1); always @(posedge gated_clk) q <= d; endmodule always
always @(posedge HCLK or negedge HRESETn) begin if (!HRESETn) HREADYOUT <= 1'b1; else begin if (HREADY && HTRANS == NONSEQ) begin if (HWRITE) memory[HADDR[11:2]] <= HWDATA; else HRDATA <= memory[HADDR[11:2]]; HREADYOUT <= 1'b1; end else HREADYOUT <= 1'b1; // wait-state insertion possible end end endmodule
// Gray code sync across domains reg [3:0] wptr_sync_r, rptr_sync_r; always @(posedge rclk) wptr_sync_r <= wgray; // + 2nd flop
// ALU inside execute wire [31:0] alu_out = (opcode == ADD) ? ID_EX_rs1 + ID_EX_rs2 : ...; ID_EX_rs1 + ID_EX_rs2 :
Gray code pointers, full/empty detection, metastability hardening. 5. Low-Power Design Techniques Clock Gating (Integrated with synthesis) module clock_gated_reg ( input clk, en, d, output reg q ); wire gated_clk; assign gated_clk = clk & en; // NOT for FPGA (glitchy) // Better: use latch-based AND gate reg en_latch; always @(clk or en) if (!clk) en_latch = en; assign gated_clk = clk & en_latch;
// Stage 2: Decode & Register Read (combinational) wire [4:0] rs1 = IF_ID_instr[19:15]; wire [4:0] rs2 = IF_ID_instr[24:20]; wire [31:0] reg_data1 = regfile[rs1]; wire [31:0] reg_data2 = regfile[rs2];
Separate pipeline registers, hazard detection (data forwarding), branch prediction. 3. Memory Controllers & Arbitration Example: AHB-Lite Slave (Burst Write) module ahb_slave ( input HCLK, HRESETn, input HTRANS, HWRITE, HREADY, input [31:0] HADDR, HWDATA, output reg HREADYOUT, HRESP, output reg [31:0] HRDATA ); reg [31:0] memory [0:1023];
// Tag SRAM, Data SRAM, LRU bits reg [19:0] tag [0:WAYS-1][0:LINE_SIZE-1]; reg [255:0] data [0:WAYS-1][0:LINE_SIZE-1];
always_comb begin next = state; case (state) IDLE: if (cpu_req) next = TAG_CHECK; TAG_CHECK: if (hit) next = HIT_FILL; else next = MISS_REFILL; ... endcase end // Implement LRU replacement, write-back vs write-through endmodule | Tool | Purpose | |------|---------| | Verilator | Fast simulation + linting | | Yosys | Synthesis to generic netlist | | OpenSTA | Static timing analysis | | GTKWave | Waveform viewing | | SymbiYosys | Formal verification (SVA) |