Files
sanbuphy f44c842fe7 feat(docs): update computer fundamentals content and demos
- Refactor frontend framework demo descriptions for clarity
- Remove interactive features from triad and field map demos
- Add new computer organization and DSL documentation links
- Split type systems and compilers into separate pages
- Enhance power-on-to-web article with relay race analogy
- Add new interactive demos for type systems and compilation
- Improve visual presentation of boot process and hardware flow
- Introduce new Vibe Coding flow demo component
2026-02-25 01:38:27 +08:00

406 lines
8.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="bus-demo">
<div class="demo-header">
<span class="title">计算机总线系统</span>
<span class="subtitle">地址总线数据总线控制总线</span>
</div>
<div class="bus-architecture">
<div class="cpu-box">
<div class="component-label">CPU</div>
<div class="cpu-internal">
<div class="cu">控制单元</div>
<div class="alu">运算单元</div>
</div>
</div>
<div class="bus-section">
<div class="bus-line address-bus" :class="{ active: activeBus === 'address' }">
<span class="bus-name">地址总线</span>
<span class="bus-width">32</span>
<div class="bus-data" v-if="activeBus === 'address'">{{ addressValue }}</div>
</div>
<div class="bus-line data-bus" :class="{ active: activeBus === 'data' }">
<span class="bus-name">数据总线</span>
<span class="bus-width">64</span>
<div class="bus-data" v-if="activeBus === 'data'">{{ dataValue }}</div>
</div>
<div class="bus-line ctrl-bus" :class="{ active: activeBus === 'control' }">
<span class="bus-name">控制总线</span>
<span class="bus-width">控制信号</span>
<div class="bus-data" v-if="activeBus === 'control'">{{ ctrlSignal }}</div>
</div>
</div>
<div class="memory-box">
<div class="component-label">主存</div>
<div class="mem-cells">
<div v-for="i in 8" :key="i" class="mem-cell" :class="{ active: activeMem === i-1 }">
{{ fmtAddr(i-1) }}
</div>
</div>
</div>
</div>
<div class="control-panel">
<div class="operation-group">
<button class="btn" @click="simulateRead">读取内存</button>
<button class="btn" @click="simulateWrite">写入内存</button>
</div>
<div class="input-group">
<input v-model.number="addressInput" type="number" placeholder="地址(0-7)" min="0" max="7" class="addr-input" />
<input v-model.number="dataInput" type="number" placeholder="数据" class="data-input" />
</div>
</div>
<div class="operation-log">
<div class="log-title">操作流程</div>
<div class="log-steps">
<div v-for="(step, i) in logSteps" :key="i" :class="['log-step', step.active ? 'active' : '']">
<span class="step-num">{{ i + 1 }}</span>
<span class="step-text">{{ step.text }}</span>
</div>
</div>
</div>
<div class="bus-explanation">
<div class="exp-title">总线知识点</div>
<div class="exp-grid">
<div class="exp-item">
<div class="exp-label">地址总线</div>
<div class="exp-desc">CPU 发送内存地址单向传输</div>
</div>
<div class="exp-item">
<div class="exp-label">数据总线</div>
<div class="exp-desc">传输实际数据双向传输</div>
</div>
<div class="exp-item">
<div class="exp-label">控制总线</div>
<div class="exp-desc">传输读/写等控制信号</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const activeBus = ref('')
const activeMem = ref(-1)
const addressValue = ref('')
const dataValue = ref('')
const ctrlSignal = ref('')
const addressInput = ref(0)
const dataInput = ref(100)
const logSteps = ref([])
const simulateRead = async () => {
logSteps.value = []
addressValue.value = addressInput.value.toString(2).padStart(32, '0').slice(-8)
activeBus.value = 'address'
logSteps.value.push({ text: `CPU 通过地址总线发送地址 ${addressInput.value}`, active: true })
await wait(1000)
activeBus.value = 'control'
ctrlSignal.value = 'READ'
logSteps.value.push({ text: '控制总线发送 READ 信号', active: true })
await wait(1000)
activeBus.value = 'data'
activeMem.value = addressInput.value
dataValue.value = Math.floor(Math.random() * 256)
logSteps.value.push({ text: `主存通过数据总线返回数据 ${dataValue.value}`, active: true })
await wait(1000)
logSteps.value.push({ text: 'CPU 接收数据到寄存器', active: true })
}
const simulateWrite = async () => {
logSteps.value = []
addressValue.value = addressInput.value.toString(2).padStart(32, '0').slice(-8)
dataValue.value = dataInput.value.toString(2).padStart(64, '0').slice(-8)
activeBus.value = 'address'
logSteps.value.push({ text: `CPU 通过地址总线发送地址 ${addressInput.value}`, active: true })
await wait(1000)
activeBus.value = 'data'
logSteps.value.push({ text: `CPU 通过数据总线发送数据 ${dataInput.value}`, active: true })
await wait(1000)
activeBus.value = 'control'
ctrlSignal.value = 'WRITE'
logSteps.value.push({ text: '控制总线发送 WRITE 信号', active: true })
await wait(1000)
activeMem.value = addressInput.value
logSteps.value.push({ text: `数据写入主存地址 ${addressInput.value}`, active: true })
}
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const fmtAddr = (addr) => '0x' + addr.toString(16).toUpperCase()
</script>
<style scoped>
.bus-demo {
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
border-radius: 12px;
padding: 20px;
margin: 16px 0;
}
.demo-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
}
.title {
font-size: 18px;
font-weight: 700;
color: #1e293b;
}
.subtitle {
font-size: 13px;
color: #64748b;
margin-left: auto;
}
.bus-architecture {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 20px;
}
.cpu-box, .memory-box {
background: white;
border-radius: 8px;
padding: 12px;
text-align: center;
}
.component-label {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
}
.cpu-internal {
display: flex;
gap: 8px;
}
.cu, .alu {
padding: 8px 12px;
background: #e0f2fe;
border-radius: 4px;
font-size: 11px;
color: #0369a1;
}
.bus-section {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.bus-line {
background: #f1f5f9;
border-radius: 4px;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
transition: all 0.3s;
}
.bus-line.active {
transform: scale(1.02);
}
.address-bus.active { background: #fef3c7; border-left: 3px solid #f59e0b; }
.data-bus.active { background: #dbeafe; border-left: 3px solid #3b82f6; }
.ctrl-bus.active { background: #fce7f3; border-left: 3px solid #ec4899; }
.bus-name {
font-weight: 600;
color: #1e293b;
min-width: 60px;
}
.bus-width {
color: #64748b;
font-size: 11px;
}
.bus-data {
margin-left: auto;
font-family: monospace;
font-size: 10px;
color: #1e293b;
}
.memory-box {
width: 100px;
}
.mem-cells {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
}
.mem-cell {
padding: 4px;
background: #f8fafc;
border-radius: 4px;
font-size: 10px;
font-family: monospace;
text-align: center;
}
.mem-cell.active {
background: #dbeafe;
border: 1px solid #3b82f6;
}
.control-panel {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.operation-group {
display: flex;
gap: 8px;
}
.btn {
padding: 8px 16px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
}
.btn:hover {
background: #2563eb;
}
.input-group {
display: flex;
gap: 8px;
}
.addr-input, .data-input {
width: 80px;
padding: 6px 10px;
border: 1px solid #e2e8f0;
border-radius: 6px;
font-size: 13px;
}
.operation-log {
background: white;
border-radius: 8px;
padding: 12px;
margin-bottom: 16px;
}
.log-title {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
}
.log-steps {
display: flex;
flex-direction: column;
gap: 4px;
}
.log-step {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
background: #f8fafc;
border-radius: 4px;
font-size: 12px;
color: #64748b;
}
.log-step.active {
background: #dbeafe;
color: #1e293b;
}
.step-num {
width: 20px;
height: 20px;
background: #e2e8f0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 600;
}
.step-text {
flex: 1;
}
.bus-explanation {
background: white;
border-radius: 8px;
padding: 12px;
}
.exp-title {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
}
.exp-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
.exp-item {
padding: 8px;
background: #f8fafc;
border-radius: 6px;
}
.exp-label {
font-size: 12px;
font-weight: 600;
color: #1e293b;
margin-bottom: 4px;
}
.exp-desc {
font-size: 11px;
color: #64748b;
}
</style>