chore: save local history restorations from accidental git restore

This commit is contained in:
sanbuphy
2026-02-23 01:40:56 +08:00
parent 780be69b99
commit 2a0fdd3392
27 changed files with 5971 additions and 2743 deletions
@@ -0,0 +1,369 @@
<template>
<div class="functional-unit-demo">
<div class="demo-label">
常见功能单元 切换不同模块查看其实际工作原理
</div>
<div class="tabs">
<button
v-for="tab in tabs"
:key="tab.id"
class="tab-btn"
:class="{ active: currentTab === tab.id }"
@click="currentTab = tab.id"
>
{{ tab.name }}
</button>
</div>
<div class="demo-content">
<!-- MUX Demo -->
<div v-if="currentTab === 'mux'" class="demo-panel">
<div class="panel-desc">
<strong>多路选择器 (MUX)</strong>像铁路道岔一样根据"选择信号"决定让哪一路数据通过
</div>
<div class="mux-container">
<div class="inputs">
<div class="input-line">
<span class="label">数据 0 (D0)</span>
<button
class="toggle-btn"
:class="{ on: muxD0 }"
@click="muxD0 = !muxD0"
>
{{ muxD0 ? '1' : '0' }}
</button>
</div>
<div class="input-line">
<span class="label">数据 1 (D1)</span>
<button
class="toggle-btn"
:class="{ on: muxD1 }"
@click="muxD1 = !muxD1"
>
{{ muxD1 ? '1' : '0' }}
</button>
</div>
</div>
<div class="mux-chip">
<div class="chip-body">MUX</div>
<div class="select-pin">
<span class="label">选择 (Sel)</span>
<button
class="select-btn"
:class="{ on: muxSel }"
@click="muxSel = !muxSel"
>
{{ muxSel ? '1' : '0' }}
</button>
</div>
</div>
<div class="outputs">
<div class="output-line" :class="{ active: muxResult }">
<span class="label">输出 (Out)</span>
<span class="out-val">{{ muxResult ? '1' : '0' }}</span>
</div>
</div>
</div>
<div class="logic-explain">
<p>
当前选择信号为 {{ muxSel ? '1' : '0' }}因此输出等于 数据
{{ muxSel ? '1 (D1)' : '0 (D0)' }} 的值<strong>{{
muxResult ? '1' : '0'
}}</strong>
</p>
</div>
</div>
<!-- Decoder Demo -->
<div v-if="currentTab === 'decoder'" class="demo-panel">
<div class="panel-desc">
<strong>译码器 (Decoder)</strong>将二进制输入转换为特定输出线的激活信号例如 2位输入可以激活
4根输出线中的一根
</div>
<div class="decoder-container">
<div class="inputs vertical">
<div class="input-line">
<button
class="toggle-btn"
:class="{ on: decA1 }"
@click="decA1 = !decA1"
>
{{ decA1 ? '1' : '0' }}
</button>
<span class="label">A1 (高位)</span>
</div>
<div class="input-line">
<button
class="toggle-btn"
:class="{ on: decA0 }"
@click="decA0 = !decA0"
>
{{ decA0 ? '1' : '0' }}
</button>
<span class="label">A0 (低位)</span>
</div>
</div>
<div class="decoder-chip">
<div class="chip-body">2-to-4<br />译码器</div>
</div>
<div class="outputs vertical-out">
<div class="output-line" :class="{ active: decResult === 0 }">
<span class="out-val">{{ decResult === 0 ? '1' : '0' }}</span>
<span class="label">Y0 (当输入 00 )</span>
</div>
<div class="output-line" :class="{ active: decResult === 1 }">
<span class="out-val">{{ decResult === 1 ? '1' : '0' }}</span>
<span class="label">Y1 (当输入 01 )</span>
</div>
<div class="output-line" :class="{ active: decResult === 2 }">
<span class="out-val">{{ decResult === 2 ? '1' : '0' }}</span>
<span class="label">Y2 (当输入 10 )</span>
</div>
<div class="output-line" :class="{ active: decResult === 3 }">
<span class="out-val">{{ decResult === 3 ? '1' : '0' }}</span>
<span class="label">Y3 (当输入 11 )</span>
</div>
</div>
</div>
<div class="logic-explain">
<p>
当前输入为二进制的 {{ decA1 ? '1' : '0'
}}{{ decA0 ? '1' : '0' }} (十进制 {{ decResult }})因此只有
<strong>Y{{ decResult }}</strong> 被激活输出 1
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const tabs = [
{ id: 'mux', name: '多路选择器 (MUX)' },
{ id: 'decoder', name: '译码器 (Decoder)' }
]
const currentTab = ref('mux')
// MUX State
const muxD0 = ref(false)
const muxD1 = ref(true)
const muxSel = ref(false)
const muxResult = computed(() => (muxSel.value ? muxD1.value : muxD0.value))
// Decoder State
const decA1 = ref(false)
const decA0 = ref(false)
const decResult = computed(() => (decA1.value ? 2 : 0) + (decA0.value ? 1 : 0))
</script>
<style scoped>
.functional-unit-demo {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: var(--vp-c-bg-soft);
padding: 1rem 1.2rem;
margin: 1rem 0;
}
.demo-label {
font-size: 0.78rem;
font-weight: bold;
color: var(--vp-c-text-2);
margin-bottom: 0.75rem;
letter-spacing: 0.2px;
}
.tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
border-bottom: 1px solid var(--vp-c-divider);
padding-bottom: 0.5rem;
}
.tab-btn {
padding: 0.4rem 0.8rem;
font-size: 0.85rem;
border-radius: 4px;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
color: var(--vp-c-text-2);
cursor: pointer;
transition: all 0.2s;
}
.tab-btn:hover {
border-color: var(--vp-c-brand-1);
}
.tab-btn.active {
background: var(--vp-c-brand-soft);
color: var(--vp-c-brand-1);
border-color: var(--vp-c-brand-1);
font-weight: bold;
}
.panel-desc {
font-size: 0.85rem;
color: var(--vp-c-text-2);
margin-bottom: 1rem;
}
/* common elements */
.toggle-btn {
width: 2rem;
height: 2rem;
border-radius: 4px;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
font-weight: bold;
font-family: monospace;
cursor: pointer;
transition: all 0.2s;
}
.toggle-btn.on {
background: var(--vp-c-green-soft, #dcfce7);
color: var(--vp-c-green-1, #16a34a);
border-color: var(--vp-c-green-1, #16a34a);
}
.out-val {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 4px;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
font-weight: bold;
font-family: monospace;
}
.output-line.active .out-val {
background: var(--vp-c-brand-soft);
color: var(--vp-c-brand-1);
border-color: var(--vp-c-brand-1);
}
.output-line.active .label {
color: var(--vp-c-brand-1);
font-weight: bold;
}
.logic-explain {
margin-top: 1rem;
padding: 0.8rem;
background: var(--vp-c-bg);
border-radius: 6px;
font-size: 0.85rem;
text-align: center;
color: var(--vp-c-text-2);
}
/* MUX Layout */
.mux-container {
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 1rem;
}
.inputs {
display: flex;
flex-direction: column;
gap: 1rem;
}
.input-line {
display: flex;
align-items: center;
gap: 0.5rem;
}
.label {
font-size: 0.8rem;
color: var(--vp-c-text-3);
font-variant-numeric: tabular-nums;
}
.mux-chip {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.chip-body {
width: 4rem;
height: 6rem;
background: var(--vp-c-bg-alt);
border: 2px solid var(--vp-c-divider);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
clip-path: polygon(0 0, 100% 20%, 100% 80%, 0 100%);
}
.select-pin {
position: absolute;
bottom: -2.5rem;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
}
.select-btn {
width: 2rem;
height: 1.5rem;
border-radius: 4px;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
font-size: 0.8rem;
cursor: pointer;
}
.select-btn.on {
background: #fef08a; /* yellow soft */
color: #a16207;
border-color: #a16207;
}
/* Decoder Layout */
.decoder-container {
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
padding: 1rem;
}
.inputs.vertical,
.outputs.vertical-out {
display: flex;
flex-direction: column;
gap: 0.8rem;
}
.decoder-chip .chip-body {
width: 5rem;
height: 8rem;
background: var(--vp-c-bg-alt);
border: 2px solid var(--vp-c-divider);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
text-align: center;
clip-path: none;
border-radius: 4px;
}
</style>