PageSourceSearch

https://simten.dev/assets/rv32i-DewVQp2H.js

js simten.dev collected 2026-09-29 07:16:28 UTC 22,072 bytes, 54 lines download raw bytes

1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BODw-YNp.js","assets/main-5zZu2UcF.js"])))=>i.map(i=>d[i]);
2import{r as m,j as n,S as q,_ as X}from"./main-5zZu2UcF.js";import{T as A,a as T,b as O,c as W}from"./tooltip-YaFWaX92.js";import{c as J,g as M,h as H,U as G,i as Y,M as K,b as R,a as z,j as Q,e as $,u as Z}from"./useCircuitSimulator-Ocs-zDtT.js";import"./index-C6v6OnJi.js";const ee=J("RV32I_CPU",{inputs:{net_rx_data:$(32),net_rx_valid:R,net_rx_frame:R,debug_addr:$(5)},outputs:{net_tx_data:$(32),net_tx_valid:R,net_tx_frame:R,pc_out:$(32),debug_value:$(32),if_pc:$(32),id_pc:$(32),ex_pc:$(32),mem_pc4:$(32),wb_pc4:$(32)},nodes:{cpu:Q({debug:!0}),imem:M,bus_mux:K,dmem:Y,uart:G,nic:H,imem_data:M,zero32:z({value:0,width:32}),zero1:z({value:0,width:1})},connect:({inputs:r,outputs:e,nodes:{cpu:i,imem:l,bus_mux:a,dmem:s,uart:u,nic:d,imem_data:p,zero32:h,zero1:g}})=>[i.instr_addr.to(l.addr),l.instruction.to(i.instruction),i.data_addr.to(a.addr),i.data_write.to(a.write_data),i.data_mem_read.to(a.mem_read),i.data_mem_write.to(a.mem_write),i.data_funct3.to(a.funct3),a.read_data.to(i.data_read),h.out.to(i.net_rx_data),g.out.to(i.net_rx_valid,i.net_rx_frame),a.local_addr.to(s.addr,u.addr,d.tx_addr,d.rx_addr,p.addr),a.write_data_out.to(s.write_data,u.write_data,d.tx_write_data),a.p0_read.to(s.mem_read),a.p0_write.to(s.mem_write),a.funct3_out.to(s.funct3),s.read_data.to(a.read_data_0),a.p1_read.to(u.mem_read),a.p1_write.to(u.mem_write),u.read_data.to(a.read_data_1),a.p2_read.to(d.tx_mem_read),a.p2_write.to(d.tx_mem_write),d.tx_read_data.to(a.read_data_2),a.p3_read.to(d.rx_mem_read),a.p3_write.to(d.rx_mem_write),d.rx_read_data.to(a.read_data_3),p.instruction.to(a.read_data_4),r.net_rx_data.to(d.net_rx_data),r.net_rx_valid.to(d.net_rx_valid),r.net_rx_frame.to(d.net_rx_frame),d.net_tx_data.to(e.net_tx_data),d.net_tx_valid.to(e.net_tx_valid),d.net_tx_frame.to(e.net_tx_frame),r.debug_addr.to(i.debug_addr),i.debug_value.to(e.debug_value),i.pc_out.to(e.pc_out),i.if_pc.to(e.if_pc),i.id_pc.to(e.id_pc),i.ex_pc.to(e.ex_pc),i.mem_pc4.to(e.mem_pc4),i.wb_pc4.to(e.wb_pc4)]}),F={0:"zero",1:"ra",2:"sp",3:"gp",4:"tp",5:"t0",6:"t1",7:"t2",8:"s0",9:"s1",10:"a0",11:"a1",12:"a2",13:"a3",14:"a4",15:"a5",16:"a6",17:"a7",18:"s2",19:"s3",20:"s4",21:"s5",22:"s6",23:"s7",24:"s8",25:"s9",26:"s10",27:"s11",28:"t3",29:"t4",30:"t5",31:"t6"};function te(r){const e=[];for(const i of r.split(`
3`)){const l=i.match(/^([0-9a-f]+)\s+<([^>]+)>:/);if(l){e.push({address:parseInt(l[1],16),label:l[2],instruction:""});continue}const a=i.match(/^\s+([0-9a-f]+):\s+(.+)$/);a&&e.push({address:parseInt(a[1],16),instruction:a[2].trim()})}return e}function re(r){const e=atob(r),i=new Map;for(let l=0;l<e.length;l++){const a=e.charCodeAt(l);a!==0&&i.set(l,a)}return i}function w(r,e,i){if(!r)return null;const l=r.get(`${e}.${i}`);return l===void 0?null:typeof l=="number"?l>>>0:null}function ne(){const[r,e]=m.useState(null),[i,l]=m.useState(null),[a,s]=m.useState(!1),[u,d]=m.useState(null),[p,h]=m.useState(!1),g=m.useRef(null),c=Z(ee);m.useEffect(()=>{!c.ready||!i||(c.setNodeValue("imem",i),c.runCombinational())},[c.ready,i]),m.useEffect(()=>(p&&c.ready&&(g.current=setInterval(()=>c.tick(),100)),()=>{g.current&&(clearInterval(g.current),g.current=null)}),[p,c.ready,c.tick]);const v=m.useCallback(async(o,_)=>{s(!0),d(null),h(!1);try{const x=await(await fetch("/api/compile",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source:o,language:_,disassemble:!0})})).json();if(!x.success||!x.binary){d(x.stderr??x.error??"Compilation failed");return}const k={binary:x.binary,disassembly:x.disassembly??""};e(k),l(re(x.binary))}catch(b){d(b instanceof Error?b.message:String(b))}finally{s(!1)}},[]),P=m.useCallback(()=>{h(!1),c.reset()},[c.reset]),j={IF:w(c.portValues,"__top__","if_pc"),ID:w(c.portValues,"__top__","id_pc"),EX:w(c.portValues,"__top__","ex_pc"),MEM:(()=>{const o=w(c.portValues,"__top__","mem_pc4");return o!=null?o-4>>>0:null})(),WB:(()=>{const o=w(c.portValues,"__top__","wb_pc4");return o!=null?o-4>>>0:null})()},[y,E]=m.useState(new Map);m.useEffect(()=>{if(!c.ready)return;let o=!1;return(async()=>{const _=await c.scanPort("debug_addr","__top__.debug_value",32);if(o||!_)return;const b=new Map;for(let x=0;x<_.length;x++)b.set(x,_[x]>>>0);E(b)})(),()=>{o=!0}},[c.ready,c.cycleCount,c.scanPort]);const N=m.useRef(new Map),C=new Set;for(const[o,_]of y)N.current.get(o)!==_&&C.add(o);
3N.current=new Map(y);const S=r?te(r.disassembly):[];return{compile:v,compiling:a,compileError:u,compiled:r,sim:c,isRunning:p,setIsRunning:h,reset:P,pipelineStages:j,registers:y,changedRegisters:C,disasmLines:S}}function t(r){const e=r.match(/^x(\d+)$/);return e?F[parseInt(e[1])]??r:r}function f(r){return"0x"+r.split(" ")[0].replace(/^0x/,"")}function ae(r){return r.split(",").map(e=>e.trim())}function I(r){if(!r)return null;const e=r.match(/^(\S+)\s+(.*)/s);if(!e)return se[r.trim()]??null;const i=e[1],l=e[2].trim(),a=ae(l),s=ie[i]??le(i);return s?s(i,a):null}const se={ret:"Return from function: jump to the address in ra (return address register).",nop:"No operation; does nothing for one cycle.",ecall:"Environment call: requests a service from the operating system.",ebreak:"Breakpoint: transfers control to the debugger.",fence:"Memory fence: ensures all memory operations before this complete before those after.",wfi:"Wait for interrupt: halts the CPU until an interrupt occurs."},ie={li:(r,e)=>`Load immediate: set ${t(e[0])} = ${e[1]}.`,la:(r,e)=>`Load address: set ${t(e[0])} to the address of ${e[1]}.`,lw:(r,e)=>`Load word: read 32 bits from memory at [${e[1]}] into ${t(e[0])}.`,lh:(r,e)=>`Load halfword: read 16 bits (sign-extended) from [${e[1]}] into ${t(e[0])}.`,lhu:(r,e)=>`Load halfword unsigned: read 16 bits (zero-extended) from [${e[1]}] into ${t(e[0])}.`,lb:(r,e)=>`Load byte: read 8 bits (sign-extended) from [${e[1]}] into ${t(e[0])}.`,lbu:(r,e)=>`Load byte unsigned: read 8 bits (zero-extended) from [${e[1]}] into ${t(e[0])}.`,sw:(r,e)=>`Store word: write 32 bits from ${t(e[0])} to memory at [${e[1]}].`,sh:(r,e)=>`Store halfword: write low 16 bits of ${t(e[0])} to memory at [${e[1]}].`,sb:(r,e)=>`Store byte: write low 8 bits of ${t(e[0])} to memory at [${e[1]}].`,mv:(r,e)=>`Move: copy ${t(e[1])} into ${t(e[0])}.`,add:(r,e)=>`Add: ${t(e[0])} = ${t(e[1])} + ${t(e[2])}.`,addi:(r,e)=>`Add immediate: ${t(e[0])} = ${t(e[1])} + ${e[2]}.`,sub:(r,e)=>`Subtract: ${t(e[0])} = ${t(e[1])} - ${t(e[2])}.`,mul:(r,e)=>`Multiply: ${t(e[0])} = ${t(e[1])} × ${t(e[2])} (lower 32 bits).`,mulh:(r,e)=>`Multiply high: ${t(e[0])} = upper 32 bits of ${t(e[1])} × ${t(e[2])} (signed).`,div:(r,e)=>`Divide: ${t(e[0])} = ${t(e[1])} ÷ ${t(e[2])} (signed).`,divu:(r,e)=>`Divide unsigned: ${t(e[0])} = ${t(e[1])} ÷ ${t(e[2])} (unsigned).`,rem:(r,e)=>`Remainder: ${t(e[0])} = ${t(e[1])} mod ${t(e[2])} (signed).`,remu:(r,e)=>`Remainder unsigned: ${t(e[0])} = ${t(e[1])} mod ${t(e[2])} (unsigned).`,neg:(r,e)=>`Negate: ${t(e[0])} = −${t(e[1])}.`,and:(r,e)=>`Bitwise AND: ${t(e[0])} = ${t(e[1])} & ${t(e[2])}.`,andi:(r,e)=>`Bitwise AND immediate: ${t(e[0])} = ${t(e[1])} & ${e[2]}.`,or:(r,e)=>`Bitwise OR: ${t(e[0])} = ${t(e[1])} | ${t(e[2])}.`,ori:(r,e)=>`Bitwise OR immediate: ${t(e[0])} = ${t(e[1])} | ${e[2]}.`,xor:(r,e)=>`Bitwise XOR: ${t(e[0])} = ${t(e[1])} ^ ${t(e[2])}.`,xori:(r,e)=>`Bitwise XOR immediate: ${t(e[0])} = ${t(e[1])} ^ ${e[2]}.`,not:(r,e)=>`Bitwise NOT: ${t(e[0])} = ~${t(e[1])}.`,sll:(r,e)=>`Shift left logical: ${t(e[0])} = ${t(e[1])} << ${t(e[2])}.`,slli:(r,e)=>`Shift left logical immediate: ${t(e[0])} = ${t(e[1])} << ${e[2]}.`,srl:(r,e)=>`Shift right logical: ${t(e[0])} = ${t(e[1])} >> ${t(e[2])} (zero-fill).`,srli:(r,e)=>`Shift right logical immediate: ${t(e[0])} = ${t(e[1])} >> ${e[2]} (zero-fill).`,sra:(r,e)=>`Shift right arithmetic: ${t(e[0])} = ${t(e[1])} >> ${t(e[2])} (sign-extend).`,srai:(r,e)=>`Shift right arithmetic immediate: ${t(e[0])} = ${t(e[1])} >> ${e[2]} (sign-extend).`,slt:(r,e)=>`Set if less than: ${t(e[0])} = 1 if ${t(e[1])} < ${t(e[2])} (signed), else 0.`,slti:(r,e)=>`Set if less than immediate: ${t(e[0])} = 1 if ${t(e[1])} < ${e[2]} (signed), else 0.`,sltu:(r,e)=>`Set if less than unsigned: ${t(e[0])} = 1 if ${t(e[1])} < ${t(e[2])} (unsigned), else 0.`,sltiu:(r,e)=>`Set if less than immediate unsigned: ${t(e[0])} = 1 if ${t(e[1])} < ${e[2]} (unsigned), else 0.`,seqz:(r,e)=>`Set if equal to zero: ${t(e[0])} = 1 if ${t(e[1])} == 0, else 0.`,snez:(r,e)=>`Set if not equal to zero: ${t(e[0])} = 1 if ${t(e[1])} ≠ 0, else 0.`,sltz:(r,e)=>`Set if less than zero: ${t(e[0])} = 1 if ${t(e[1])} < 0, else 0.`,sgtz:(r,e)=>`Set if greater than zero: ${t(e[0])} = 1 if ${t(e[1])} > 0, else 0.`,beq:(r,e)=>`Branch if equal: jump to ${f(e[2])} if ${t(e[0])} == ${t(e[1])}.`,bne:(r,e)=>`Branch if not equal: jump to ${f(e[2])} if ${t(e[0])} ≠ ${t(e[1])}.`,blt:(r,e)=>`Branch if less than: jump to ${f(e[2])} if ${t(e[0])} < ${t(e[1])} (signed).`,bge:(r,e)=>`Branch if greater or equal: jump to ${f(e[2])} if ${t(e[0])} ≥ ${t(e[1])} (signed).`,bltu:(r,e)=>`Branch if less than unsigned: jump to ${f(e[2])} if ${t(e[0])} < ${t(e[1])} (unsigned).`,bgeu:(r,e)=>`Branch if greater or equal unsigned: jump to ${f(e[2])} if ${t(e[0])} ≥ ${t(e[1])} (unsigned).`,beqz:(r,e)=>`Branch if zero: jump to ${f(e[1])} if ${t(e[0])} == 0.`,bnez:(r,e)=>`Branch if not zero: jump to ${f(e[1])} if ${t(e[0])} ≠ 0.`,bltz:(r,e)=>`Branch if negative: jump to ${f(e[1])} if ${t(e[0])} < 0.`,bgtz:(r,e)=>`Branch if positive: jump to ${f(e[1])} if ${t(e[0])} > 0.`,blez:(r,e)=>`Branch if ≤ zero: jump to ${f(e[1])} if ${t(e[0])} ≤ 0.`,bgez:(r,e)=>`Branch if ≥ zero: jump to ${f(e[1])} if ${t(e[0])} ≥ 0.`,jal:(r,e)=>e.length===1?`Jump: unconditionally jump to ${f(e[0])}.`:`Jump and link: set ${t(e[0])} = PC+4 (return address), then jump to ${f(e[1])}.`,jalr:(r,e)=>`Jump and link register: set ${t(e[0])} = PC+4, then jump to ${e[1]}.`,j:(r,e)=>`Jump: unconditionally jump to ${f(e[0])}.`,jr:(r,e)=>`Jump register: jump to the address in ${t(e[0])}.`,call:(r,e)=>`Call function at ${f(e[0])}
3, saving the return address in ra.`,tail:(r,e)=>`Tail call to ${f(e[0])}, which does not save a return address.`,lui:(r,e)=>`Load upper immediate: set ${t(e[0])} = ${e[1]} shifted left 12 bits.`,auipc:(r,e)=>`Add upper immediate to PC: ${t(e[0])} = PC + (${e[1]} << 12). Used to compute addresses relative to the current instruction.`};function le(r){return r.startsWith("fence")?()=>"Memory fence: enforces ordering of memory operations.":null}const oe=m.lazy(()=>X(()=>import("./index-BODw-YNp.js"),__vite__mapDeps([0,1]))),L=[{id:"c",label:"C",monaco:"c"},{id:"cpp",label:"C++",monaco:"cpp"},{id:"asm",label:"Assembly",monaco:"plaintext"},{id:"rust",label:"Rust",monaco:"rust"}],D={c:`// Fibonacci sequence: computes the 10th number.
4// When done, register a0 = 55 (0x00000037).
5int main() {
6    int a = 0;
7    int b = 1;
8    for (int i = 0; i < 10; i++) {
9        int tmp = a + b;
10        a = b;
11        b = tmp;
12    }
13    return a; // a0 = 55 (0x37)
14}`,cpp:`// Fibonacci sequence: computes the 10th number.
15// When done, register a0 = 55 (0x00000037).
16int main() {
17    int a = 0, b = 1;
18    for (int i = 0; i < 10; i++) {
19        int tmp = a + b;
20        a = b;
21        b = tmp;
22    }
23    return a; // a0 = 55 (0x37)
24}`,asm:`# Simple addition: 3 + 4 = 7
25# When done, register a0 = 7 (0x00000007).
26.section .text
27.global _start
28_start:
29    li a0, 3       # a0 = 3
30    li a1, 4       # a1 = 4
31    add a0, a0, a1 # a0 = a0 + a1 = 7 (0x07)
32    li a7, 93
33    ecall`,rust:`// Bare-metal Rust: no OS, no stdlib.
34// This runs directly on the CPU hardware.
35// When done, register a0 = 55 (0x00000037).
36#![no_std]
37#![no_main]
38
39use core::panic::PanicInfo;
40
41#[panic_handler]
42fn panic(_: &PanicInfo) -> ! { loop {} }
43
44#[no_mangle]
45pub extern "C" fn main() -> i32 {
46    let mut a: i32 = 0;
47    let mut b: i32 = 1;
48    for _ in 0..10 {
49        let tmp = a + b;
50        a = b;
51        b = tmp;
52    }
53    a // returned in a0 = 55 (0x37)
54}`},de={IF:{label:"Fetch",title:"Instruction Fetch",desc:"Read the next instruction from memory at the current program counter (PC)."},ID:{label:"Decode",title:"Instruction Decode",desc:"Decode the instruction, read source registers from the register file, and generate control signals."},EX:{label:"Compute",title:"Execute",desc:"The ALU performs the computation: arithmetic, logic, or address calculation."},MEM:{label:"Memory",title:"Memory Access",desc:"Load or store data in RAM. For non-memory instructions this stage passes values through unchanged."},WB:{label:"Save",title:"Write Back",desc:"Write the result back to the destination register in the register file."}},V={IF:"bg-purple-500/20 text-purple-300 border-purple-500/40",ID:"bg-blue-500/20 text-blue-300 border-blue-500/40",EX:"bg-cyan-500/20 text-cyan-300 border-cyan-500/40",MEM:"bg-amber-500/20 text-amber-300 border-amber-500/40",WB:"bg-green-500/20 text-green-300 border-green-500/40"};function U(r){return"0x"+r.toString(16).padStart(8,"0")}function ce(r,e,i){if(i===0)return"Press Step to advance one clock cycle, or Run to execute continuously.";const l=[];if(r.EX!=null){const a=e.find(s=>s.address===r.EX&&s.instruction);if(a){const s=I(a.instruction);s&&l.push(s)}}if(r.WB!=null){const a=e.find(s=>s.address===r.WB&&s.instruction);if(a){const s=I(a.instruction);s&&s.includes("=")&&r.EX!==r.WB&&l.push("Writing result to register file.")}}if(l.length===0){const a=Object.values(r).filter(s=>s!=null).length;return a===0?"Pipeline is empty; all instructions have completed.":a<5?"Pipeline is filling; instructions flow through one stage per cycle.":null}return l.join(" ")}function ue({stage:r,pc:e,instruction:i}){const l=V[r],{label:a,title:s,desc:u}=de[r];return n.jsxs(T,{children:[n.jsx(O,{asChild:!0,children:n.jsxs("div",{className:`flex flex-col rounded-lg border px-2 py-1.5 cursor-help min-w-0 flex-1 ${l}`,children:[n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"text-[11px] font-semibold",children:a}),n.jsx("span",{className:"text-[9px] font-mono opacity-40",children:r})]}),n.jsx("span",{className:"font-mono text-[10px] tabular-nums opacity-40",children:e!=null?U(e):n.jsx("span",{className:"opacity-30",children:"——"})}),n.jsx("span",{className:"mt-0.5 text-[10px] leading-tight",children:i??n.jsx("span",{className:"opacity-20",children:"——"})})]})}),n.jsxs(W,{side:"bottom",className:"max-w-64 text-center",children:[n.jsx("p",{className:"font-semibold",children:s}),n.jsx("p",{className:"mt-0.5 opacity-80",children:u})]})]})}function me({lines:r,stages:e}){const i=new Set(Object.values(e).filter(s=>s!=null)),l=new Map;for(const[s,u]of Object.entries(e))if(u!=null){const d=l.get(u)??[];d.push(s),l.set(u,d)}const a=m.useRef(null);return m.useEffect(()=>{a.current?.scrollIntoView({block:"nearest",behavior:"smooth"})},[e.IF]),n.jsx(A,{delayDuration:400,children:n.jsx("div",{className:"h-full overflow-y-auto font-mono text-xs leading-6",children:r.length===0?n.jsx("div",{className:"flex h-full items-center justify-center text-gray-600",children:"Compile code to see disassembly"}):r.map((s,u)=>{if(s.label!=null&&s.instruction==="")return n.jsxs("div",{className:"mt-3 px-4 text-amber-400 first:mt-0",children:["<",s.label,">",":"]},u);const d=i.has(s.address),p=l.get(s.address)??[],h=I(s.instruction),g=n.jsxs("div",{ref:d?a:void 0,className:`flex items-center gap-3 px-4 transition-colors ${d?"bg-blue-500/10":"hover:bg-gray-800/40"} ${h?"cursor-help":""}`,children:[n.jsx("span",{className:"w-20 shrink-0 text-gray-600 tabular-nums",children:s.address.toString(16).padStart(8,"0")}),n.jsx("span",{className:`flex-1 ${d?"text-white":"text-gray-400"}`,children:s.instruction}),n.jsx("div",{className:"flex shrink-0 gap-1",children:p.map(c=>n.jsx("span",{className:`rounded px-1 py-0.5 text-[9px] font-bold uppercase border ${V[c]}`,children:c},c))})]});return h?n.jsxs(T,{children:[n.jsx(O,{asChild:!0,children:g}),n.jsx(W,{side:"right",className:"max-w-64",children:h})]},u):g})})})}function fe({registers:r,changed:e}){const i=[10,11,12,13,14,15,16,17,5,6,7,1,2,28,29,30,31],l=Array.from({length:32},(s,u)=>u).filter(s=>s!==0&&!i.includes(s)),a=[0,...i,...l];return n.jsx("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-x-3 gap-y-0.5 font-mono text-xs",children:a.map(s=>
54{const u=s===0?0:r.get(s)??0,d=u!==0,p=e.has(s);return n.jsxs("div",{className:`flex items-center gap-1.5 py-0.5 rounded px-1 -mx-1 transition-colors ${p?"bg-green-500/10":""}`,children:[n.jsx("span",{className:`w-7 shrink-0 text-[11px] ${p?"text-green-400":"text-gray-500"}`,children:F[s]}),n.jsx("span",{className:`tabular-nums truncate ${p?"text-green-300":d?"text-gray-200":"text-gray-700"}`,children:U(u)})]},s)})})}function pe(){const{compile:r,compiling:e,compileError:i,compiled:l,sim:a,isRunning:s,setIsRunning:u,reset:d,pipelineStages:p,registers:h,changedRegisters:g,disasmLines:c}=ne(),[v,P]=m.useState("c"),[j,y]=m.useState(D.c),E=o=>{P(o),y(D[o]??"")},N=()=>r(j,v),C=!!l&&!a.ready,S=a.ready?ce(p,c,a.cycleCount):null;return n.jsxs("div",{className:"flex h-full flex-col bg-gray-950 text-gray-100 overflow-hidden",children:[!l&&!e&&n.jsx("div",{className:"shrink-0 border-b border-blue-900/30 bg-blue-950/20 px-4 py-3",children:n.jsxs("p",{className:"text-sm text-blue-200/90",children:[n.jsx("span",{className:"font-semibold text-blue-100",children:"This is a real CPU"}),", built from registers, ALUs, muxes, and memory, simulated cycle by cycle in your browser. Write code in C, C++, Rust, or assembly, compile it, then step through each clock cycle and watch instructions flow through the pipeline."]})}),n.jsx(q,{sticky:!1,right:n.jsxs("div",{className:"flex flex-1 items-center gap-2 flex-wrap justify-end",children:[n.jsx("span",{className:"text-sm font-semibold text-foreground/80 mr-auto pl-2 border-l border-border",children:"RV32I CPU"}),n.jsx("div",{className:"flex gap-1",children:L.map(o=>n.jsx("button",{onClick:()=>E(o.id),className:`px-2.5 py-1 rounded text-xs font-medium transition-colors ${v===o.id?"bg-blue-600 text-white":"text-muted-foreground hover:text-foreground hover:bg-muted"}`,children:o.label},o.id))}),n.jsx("div",{className:"h-4 w-px bg-border"}),n.jsx("button",{onClick:N,disabled:e,className:"px-3 py-1 rounded text-xs font-medium bg-blue-600 hover:bg-blue-500 text-white transition-colors disabled:opacity-50",children:e?"Compiling…":"Compile"}),a.ready&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"h-4 w-px bg-border"}),n.jsx("button",{onClick:a.tick,disabled:s,className:"px-3 py-1 rounded text-xs font-medium bg-muted hover:bg-muted/80 text-foreground transition-colors disabled:opacity-40",children:"Step"}),n.jsx("button",{onClick:()=>u(!s),className:`px-3 py-1 rounded text-xs font-medium transition-colors ${s?"bg-amber-600 hover:bg-amber-500 text-white":"bg-green-700 hover:bg-green-600 text-white"}`,children:s?"Pause":"Run"}),n.jsx("button",{onClick:d,className:"px-3 py-1 rounded text-xs font-medium bg-muted hover:bg-muted/80 text-foreground transition-colors",children:"Reset"}),n.jsxs("span",{className:"ml-1 font-mono text-xs text-muted-foreground tabular-nums",children:["Cycle ",a.cycleCount.toLocaleString()]})]}),C&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"h-4 w-px bg-border"}),n.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[n.jsx("div",{className:"h-3 w-3 animate-spin rounded-full border border-muted-foreground/30 border-t-blue-400"}),"Building simulator…"]})]})]})}),n.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[n.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden border-r border-gray-800",children:[n.jsxs("div",{className:"shrink-0 border-b border-gray-800 px-3 py-2",children:[n.jsx("div",{className:"mb-1.5 text-[10px] font-semibold uppercase tracking-widest text-gray-600",children:"Pipeline"}),n.jsx(A,{delayDuration:300,children:n.jsx("div",{className:"flex gap-1.5 overflow-x-auto",children:["IF","ID","EX","MEM","WB"].map(o=>{const _=p[o],b=_!=null?c.find(B=>B.address===_&&B.instruction)?.instruction??null:null,x=b?I(b):null,k=x?x.split(".")[0]:b??null;return n.jsx(ue,{stage:o,pc:_,instruction:k},o)})})}),S&&n.jsx("p",{className:"mt-1.5 text-[11px] text-gray-400 leading-relaxed",children:S})]}),n.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[n.jsxs("div",{className:"flex w-[45%] flex-col border-r border-gray-800",children:[n.jsx("div",{className:"flex-1 min-h-0",children:n.jsx(m.Suspense,{fallback:n.jsx("textarea",{value:j,onChange:o=>y(o.target.value),spellCheck:!1,className:"h-full w-full resize-none bg-gray-950 font-mono text-xs text-gray-300 p-4 leading-relaxed focus:outline-none"}),children:n.jsx(oe,{height:"100%",language:L.find(o=>o.id===v)?.monaco??"c",value:j,onChange:o=>y(o??""),theme:"vs-dark",options:{fontSize:13,minimap:{enabled:!1},lineNumbers:"on",scrollBeyondLastLine:!1,renderLineHighlight:"none",overviewRulerLanes:0,hideCursorInOverviewRuler:!0,scrollbar:{vertical:"hidden",horizontal:"hidden"},padding:{top:12},wordWrap:"on",tabSize:4,automaticLayout:!0}})})}),i&&n.jsx("div",{className:"shrink-0 border-t border-red-800/50 bg-red-950/20 p-3",children:n.jsx("pre",{className:"font-mono text-xs text-red-400 whitespace-pre-wrap max-h-40 overflow-auto",children:i})})]}),n.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[n.jsx("div",{className:"shrink-0 border-b border-gray-800 px-4 py-1.5 text-[10px] font-semibold uppercase tracking-widest text-gray-600",children:"Disassembly"}),n.jsx(me,{lines:c,stages:p})]})]})]}),n.jsxs("div",{className:"flex w-[300px] shrink-0 flex-col overflow-hidden",children:[n.jsx("div",{className:"shrink-0 border-b border-gray-800 px-4 py-1.5 text-[10px] font-semibold uppercase tracking-widest text-gray-600",children:"Registers"}),n.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:n.jsx(fe,{registers:h,changed:g})})]})]})]})}const be=()=>n.jsx("div",{className:"h-screen",children:n.jsx(pe,{})});
54export{be as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.