name: "Single-Cycle RV32I Micro Core"
category: "Soft Processors & Memory"
complexity: "Hard"
description: >
  Implement a single-cycle 32-bit RISC-V subset CPU core with separate
  instruction and data memory interfaces. The core executes one instruction
  per clock cycle when not halted or trapped. It contains 32 architectural
  registers x0..x31 and a 32-bit program counter. Register x0 is hardwired
  to zero: reads of x0 must return 0 and writes to x0 must be ignored.

  The core supports the following standard RV32I instructions and encodings:
  LUI, ADDI, ADD, SUB, AND, OR, XOR, LW, SW, BEQ, BNE, JAL, and EBREAK.
  Any other instruction encoding is illegal and must raise `trap`.

  EXECUTION MODEL:
  - `imem_addr` must always be the current PC.
  - `imem_rdata` is the 32-bit instruction located at `imem_addr`.
  - One instruction is fetched and executed each cycle.
  - If neither `halted` nor `trap` is asserted, architectural state updates
    on the rising edge of `clk`.
  - The default next PC is PC + 4.

  INSTRUCTION SEMANTICS:
  - LUI: rd = imm_u.
  - ADDI: rd = rs1 + sign_extended_imm_i.
  - ADD, SUB, AND, OR, XOR: standard RV32I register-register operations.
  - LW: rd = 32-bit word read from data memory at address
    rs1 + sign_extended_imm_i.
  - SW: store rs2 to data memory at address rs1 + sign_extended_imm_s.
  - BEQ, BNE: if the condition is true, next PC = PC + sign_extended_imm_b,
    otherwise next PC = PC + 4.
  - JAL: rd = PC + 4 and next PC = PC + sign_extended_imm_j.
  - EBREAK: assert `halted` on the next rising edge and stop execution.

  MEMORY MODEL:
  - Instruction and data addresses are byte addresses.
  - Instruction fetches are always 32-bit aligned.
  - LW and SW operate on full 32-bit words only.
  - For LW, `dmem_rdata` provides the 32-bit word stored at `dmem_addr`
    in the same cycle.
  - For SW, a write occurs on the rising clock edge when `dmem_we` is high.
  - `dmem_we` must be high only for SW and low for all other instructions.

  TRAP CONDITIONS:
  - Unsupported or illegal instruction encoding.
  - LW or SW effective address not aligned to 4 bytes.
  - A taken BEQ/BNE target not aligned to 4 bytes.
  - A JAL target not aligned to 4 bytes.
  - When `trap` is raised, no register write and no memory write may occur
    for that instruction.

  HALT/TRAP BEHAVIOUR:
  - Once `halted` or `trap` is high, the core must stop updating PC and
    registers, and `dmem_we` must remain low.
  - `halted` and `trap` are sticky until reset.

  RESET:
  - `rst` is synchronous and active-high.
  - On reset, set PC to 0, clear all registers to 0, clear `halted` and
    `trap`, and deassert `dmem_we`.

interface:
  module_name: "rv32_micro_core"
  clocked: true
  ports:
    - name: "clk"
      type: "input"
      width: "1"
      description: "Clock signal"
    - name: "rst"
      type: "input"
      width: "1"
      description: "Synchronous active-high reset"
    - name: "imem_addr"
      type: "output"
      width: "32"
      description: "Instruction memory byte address, equal to current PC"
    - name: "imem_rdata"
      type: "input"
      width: "32"
      description: "Instruction word at imem_addr"
    - name: "dmem_addr"
      type: "output"
      width: "32"
      description: "Data memory byte address for loads and stores"
    - name: "dmem_wdata"
      type: "output"
      width: "32"
      description: "Store data for SW"
    - name: "dmem_we"
      type: "output"
      width: "1"
      description: "Data memory write enable, high only for SW"
    - name: "dmem_rdata"
      type: "input"
      width: "32"
      description: "Load data returned for LW"
    - name: "halted"
      type: "output"
      width: "1"
      description: "Sticky high after EBREAK executes"
    - name: "trap"
      type: "output"
      width: "1"
      description: "Sticky high after an illegal or misaligned operation"

target_platform:
  device_family: "AMD Xilinx Zynq-7000"

tasks:
  - name: "Area-Efficient RV32I Subset CPU"
    constraints:
      max_lut: 1400
      max_ff: 1100
      max_bram: 0
      max_dsp: 0
      min_frequency: 50
    objective:
      goal: "minimise"
      target: "LUT"
