Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Paths
  • Concept Map
  • How to Read the Diagrams
  • Part 0: What Is a Protocol?10
  • Part 1: Timing and Clocking11
  • Part 2: Encoding and Framing12
  • Part 3: Handshakes13
  • Part 4: Flow Control17
  • Part 5: Transactions19
  • Part 6: Concurrency and Performance17
  • Part 7: Ordering13
  • Part 8: Sharing and Arbitration12
  • Part 9: Deadlock and Liveness13
  • Part 10: Reliability and Recovery20
  • Part 11: Bring-Up and Link Management10
  • Part 12: Power8
  • Part 13: Shared State and Coherence9
  • Part 14: Security and Isolation7
    • Access Attributes
    • Firewalls and Filtering
    • Address Translation for Devices
    • Link Integrity and Encryption
    • Fabric Denial of Service
    • Isolation and Multi-Tenancy
    • Drills: Security and Isolation
  • Part 15: Specifying and Verifying11
  • Part 16: Protocols Dissected17
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 14: Security and Isolation
  1. Topics
  2. First Principles of Hardware Protocols
  3. Part 14: Security and Isolation
  4. Firewalls and Filtering

Part 14 · Security and Isolation · Senior (S)

Firewalls and Filtering

A firewall in the fabric compares each request's address and attributes with a table of regions and refuses what is not allowed, before it reaches the target. How it decides, where to put it, and why a refused request must still get an answer. Built and simulated.

On this page

    Note

    Level: Senior (S) · Answers: Who is allowed to ask?

    Before this: Access Attributes, Error Responses

    A system has secure memory for keys, ordinary memory for everyone, and peripherals some agents may program and others may not. Each target could check every request itself, but most targets (a memory, a simple peripheral) know nothing about security states or requester IDs. The check has to sit in the fabric, in front of them, and look at every request on the way through.

    How does a firewall in the fabric decide which requests reach a target?

    The obvious answer, and why it breaks

    The obvious answer is to drop disallowed requests. Dropping breaks the rule that every request gets a response (lesson 5.2): the requester waits for ever, and a buggy or hostile requester can now hang itself or, worse, a shared bridge. The firewall must refuse and answer: return an error response, so the requester completes and software can see what happened.

    The idea: a region table, checked per request

    Region

    Addresses

    Rule

    0

    0x00 to 0x3F

    Secure requests only

    1

    0x40 to 0x7F

    Anyone

    (none)

    Everything else

    Unmapped: refuse

    • Match: find the region containing the address (and, for multi-beat requests, check that the whole burst stays inside it).

    • Check: compare the request's attributes (security state, privilege, requester ID, read or write) with the region's rule.

    • Allow or refuse: allowed requests pass unchanged; refused ones never reach the target and are answered with an error. Reads return no real data (often zeros).

    • Record: log the refused address and requester, and raise an interrupt to secure software.

    Build it: a two-region firewall

    Four requests: secure to region 0, non-secure to region 0, non-secure to region 1, secure to an unmapped address.

    tb.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    // An address-range firewall in front of a target. Each request carries an address
    // and a non-secure bit (ns, as AXI's AxPROT[1]). Region 0 (0x00-0x3F) is secure
    // only; region 1 (0x40-0x7F) is open to everyone; any other address is unmapped.
    // Allowed requests pass to the target; refused ones never reach it and get an error
    // response (deny), so the requester does not hang. Four requests, cycles 1 to 4:
    // secure to region 0 (pass), non-secure to region 0 (deny), non-secure to region 1
    // (pass), secure to an unmapped address (deny).
    module tb;
      logic clk = 0;
      always #5 clk = ~clk;
      initial begin $dumpfile("wave.vcd"); $dumpvars(0, tb); end
    
      int cyc = 0;
      always @(posedge clk) cyc <= cyc + 1;
    
      logic       req = 0, ns = 0;
      logic [7:0] addr = 0;
      always @(posedge clk) begin
        req <= 0; addr <= 0; ns <= 0;
        case (cyc)
          0: begin req <= 1; addr <= 8'h10; ns <= 0; end
          1: begin req <= 1; addr <= 8'h10; ns <= 1; end
          2: begin req <= 1; addr <= 8'h50; ns <= 1; end
          3: begin req <= 1; addr <= 8'h90; ns <= 0; end
          default: ;
        endcase
      end
    
      // The firewall: decide per request, in one cycle
      logic allowed;
      always_comb begin
        if (addr < 8'h40)      allowed = !ns;      // region 0: secure only
        else if (addr < 8'h80) allowed = 1'b1;     // region 1: anyone
        else                   allowed = 1'b0;     // unmapped
      end
      logic pass = 0, deny = 0;
      always @(posedge clk) begin
        pass <= req && allowed;                    // forwarded to the target
        deny <= req && !allowed;                   // answered with an error here
      end
    
      int passed = 0, denied = 0, leaked = 0;
      logic [7:0] addr_q = 0; logic ns_q = 0;
      always @(posedge clk) begin
        addr_q <= addr; ns_q <= ns;
        if (pass) begin passed++; if ((addr_q < 8'h40 && ns_q) || addr_q >= 8'h80) leaked++; end
        if (deny) denied++;
      end
      initial begin
        #120;
        if (passed == 2 && denied == 2 && leaked == 0)
          $display("PASS: two requests passed, the non-secure access to secure memory and the unmapped access were refused with errors");
        else $display("FAIL: passed %0d denied %0d leaked %0d", passed, denied, leaked);
        $finish;
      end
    endmodule

    Watch it run

    How to read it, slot by slot (allowed is the firewall's decision for whatever is on addr and ns; it matters only while req is high):

    • Slot 0: secure request (ns = 0) to 0x10: allowed; slot 1: pass.

    • Slot 1: non-secure request (ns = 1) to the same address: refused; slot 2: deny, an error response.

    • Slot 2: non-secure request to 0x50 in the open region: allowed; slot 3: pass.

    • Slot 3: secure request to 0x90, unmapped: refused; slot 4: deny.

    Where to put firewalls

    Placement

    Protects

    Note

    In front of a target (memory, peripheral)

    That target, from every requester

    Common for memory controllers and secure peripherals

    At a requester's port into the fabric

    Everything, from that requester

    Good for untrusted agents such as DMA engines and debug

    In the interconnect's address decoder

    Whole address ranges

    Cheap, coarse

    The firewall's own configuration (its region table) must itself be protected: writable only by secure, privileged software, or locked after boot. A firewall anyone can reprogram is no firewall.

    How real protocols chose

    System

    Firewalls

    Arm TrustZone systems

    A TrustZone address space controller such as the TZC-400 in front of memory permits or refuses each access by region, security state and master ID (fact A27); refused accesses get error responses.

    AXI

    Refused requests are answered with SLVERR or DECERR (fact A6 and lesson 10.7).

    PCI Express

    Access control services in switches can block or redirect peer-to-peer requests; an IOMMU checks DMA (lesson 14.3).

    What breaks

    A firewall (illustrative) checked only a request's start address. A non-secure burst starting at the last allowed address of an open region ran 64 bytes into the secure region next to it, and the firewall let it through. Checking that every byte of the burst falls inside one permitted region fixed it; boundary-crossing bursts are a standard firewall test.

    Why this matters

    Senior lens. A firewall's rules are only as good as its corner cases: bursts that cross region boundaries, wrapping bursts, unaligned accesses, requests during reconfiguration, and the protection of its own configuration registers. Always answer refused requests with an error, log them, and test every region edge with every attribute combination.

    Interview

    Asked: "What should a fabric firewall do with a request it refuses?"

    Weak answer: Drop it.

    Strong answer: Stop it from reaching the target, but still answer it: return an error response, such as SLVERR or DECERR on AXI, with no real data for a read, so the requester completes instead of hanging and software can see the failure. It should also log the address and requester and interrupt secure software. And the firewall must check the whole burst, not only the start address, and protect its own configuration so only secure software can change the rules.

    Follow-ups: (1) Why check the whole burst? (2) Who may program the firewall?

    Check yourself In the simulation, why does the request to 0x90 get denied even though it is secure?

    0x90 lies outside both regions: it is unmapped, so it is refused whatever its attributes.

    Check yourself Why must a firewall answer refused requests rather than drop them?

    Every request needs a response; a dropped one leaves its requester waiting for ever.

    Key takeaways

    • A firewall matches each request's address to a region and checks its attributes against the region's rule.

    • Refused requests never reach the target and are answered with an error, then logged.

    • Check whole bursts, protect the firewall's own configuration, and test every region edge.

    Keep going

    Next: Lesson 14.3, Address Translation for Devices. Giving every device its own view of memory: IOMMUs.

    Related topics

    • Part 14 overview: Security and Isolation

    Previous

    190 / 234

    Next: Address Translation for Devices

    Up next

    Up nextAddress Translation for Devices

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Link Integrity and Encryption
    • Fabric Denial of Service
    • Isolation and Multi-Tenancy
    clkreqaddr1050900nsallowedpassdeny
    Simulation output: the secure access and the open-region access pass; the non-secure access to secure memory and the unmapped access are refused with error responses.