22 / 24 · प्रयोग
समापन प्रयोगशाला: FIFO और दो चरणों का स्ट्रीमिंग कैलकुलेटर
गहराई-दो इनपुट FIFO, दो लचीले चरण और स्कोरबोर्ड जोड़ें।
पाठ पढ़ना मुफ़्त है। प्रगति सेव करने के लिए नामांकन करें।
भंडारण, गणना और वितरण जोड़ें
समापन परियोजना में दो-प्रविष्टि इनपुट FIFO और दो लचीले गणना चरण हैं। पहला चरण नौ-बिट a+b योग; दूसरा 3×sum मॉड्यूलो 256 रखता है। टैग हर मान के साथ चलते हैं। कुल क्षमता चार लेनदेन है। आउटपुट से बैकप्रेशर पीछे जाता है, जबकि खाली स्थान भर सकते हैं। एक क्लॉक, रजिस्टर FIFO, साथ pop/push और सीधे आउटपुट पार न होना मानें।
स्वयं capstone-model.mjs सहेजें और node capstone-model.mjs चलाएँ। FIFO और रजिस्टर अपडेट करने से पहले पुरानी स्थिति से सारी readiness और अगले-चरण मान निकालें। JavaScript सरणी कार्यात्मक कतार है, संश्लेषण योग्य HDL नहीं।
import assert from 'node:assert/strict';
const input = [[0,0],[1,2],[250,10],[255,255],
[128,128],[17,240],[90,90],[4,8]];
const q = [], expected = [], seen = [];
let s1 = null, s2 = null, issued = 0, delivered = 0;
for (let edge = 0; edge < 50; edge++) {
const ready = edge >= 25 || ![2,3,4].includes(edge % 7);
const old1 = s1, old2 = s2;
const r2 = old2 === null || ready;
const r1 = old1 === null || r2;
const pop = q.length > 0 && r1;
const inReady = q.length < 2 || pop;
if (old2 !== null && ready) {
assert.deepEqual(old2, expected.shift());
seen.push(old2.y);
delivered++;
}
const n2 = r2 ? (old1 === null ? null :
{ tag: old1.tag, y: old1.sum * 3 % 256 }) : old2;
const n1 = r1 ? (pop ?
{ tag: q[0].tag, sum: q[0].a + q[0].b } : null) : old1;
if (pop) q.shift();
if (issued < input.length && inReady) {
const [a,b] = input[issued];
q.push({ tag: issued, a, b });
expected.push({ tag: issued, y: (3*a + 3*b) % 256 });
issued++;
}
s1 = n1; s2 = n2;
if (old2 !== null && !ready) assert.deepEqual(s2, old2);
assert.ok(q.length <= 2);
assert.equal(issued - delivered,
q.length + Number(s1 !== null) + Number(s2 !== null));
}
assert.equal(issued, input.length);
assert.equal(delivered, input.length);
assert.deepEqual(seen, [0,9,12,250,0,3,28,36]);
assert.equal(expected.length + q.length, 0);
assert.equal(s1, null); assert.equal(s2, null);
console.log('CAPSTONE PASS: 8 ordered outputs, drained');| टैग | a,b | चौड़ा परिणाम | y |
|---|---|---|---|
| 2 | 250,10 | 780 | 12 |
| 3 | 255,255 | 1530 | 250 |
| 5 | 17,240 | 771 | 3 |
पहला इनपुट किनारा 0 पर FIFO, 1 पर s1 और 2 पर s2 में आता है। किनारा 2,3,4 के प्राप्तकर्ता स्टॉल से वितरण 5 तक टलता है। बिना स्टॉल विलंबता तीन किनारे है; यह लेनदेन पाँच लेता है। s2 स्थिर रहते अन्य खाली भंडारण भरता है।
संदर्भ कतार केवल स्वीकृति पर अपेक्षित मान निकालती है। वितरण पर टैग तथा परिणाम तुलना करें और हर किनारे भरे स्थान जाँचें। किनारा 25 के बाद सब निकालें। Node रन आठ क्रमबद्ध परिणाम जाँचता है;नीचे की SystemVerilog फ़ाइलें वास्तविक FIFO और पाइपलाइन रजिस्टर स्वतंत्र रूप से परखती हैं।
RTL बनाएँ और सिम्युलेट करें
dp_stream_calculator.sv और tb_dp_stream_calculator.sv एक फ़ोल्डर में डाउनलोड करें। चिह्नरहित आठ-बिट a,b,tag इंटरफ़ेस in-valid/in-ready पर स्वीकारता और out-valid/out-ready पर टैग के साथ y देता है। नौ-बिट योग और ग्यारह-बिट स्केल मान केवल आउटपुट पर संकरे होते हैं। रीसेट भंडारण खाली करता और स्थानांतरण रोकता है।
Icarus Verilog स्थापित होने पर चलाएँ:
iverilog -g2012 -Wall -s tb_dp_stream_calculator -o dp-test.vvp dp_stream_calculator.sv tb_dp_stream_calculator.sv
vvp dp-test.vvpलेखक के सत्यापन में इन फ़ाइलों का सफल संकलन और सिम्युलेशन हुआ:
RTL PASS: accepted=527 delivered=523 canceled=4 stalls=517 full_replace=64 wraps=262 reset_with_work=1 zero=3टेस्टबेंच अंकगणित,टैग,क्रम,स्टॉल,भरे में प्रतिस्थापन,पॉइंटर वापसी,चार-आइटम रीसेट रद्द और निकासी जाँचता है। स्टॉल अवधि बदलें और विलंबता तीन बिना स्टॉल चक्र से तुलना करें। यह Icarus RTL सिम्युलेशन जाँचता है,संश्लेषण,भौतिक समय या DDS निष्पादन नहीं।
खुद आज़माएँ
हमेशा तैयार प्राप्तकर्ता में tag0 किस किनारे पर जाता है? FIFO गहराई एक हो तो बिना स्टॉल विलंबता और कुल क्षमता क्या होंगी?
व्याख्या पढ़ें
0 पर स्वीकृति, 1 पर s1 और 2 पर s2 के बाद Tag0 किनारा 3 पर जाता है। रजिस्टर FIFO रखने से तीन-किनारा विलंबता बनी रहती है; क्षमता 1+1+1=3 लेनदेन होती है। input-ready की गहराई सीमा बदलकर मॉडल फिर जाँचें।