โครงการ | Forth SoC เขียนด้วย VHDL |
---|---|
ผู้เขียน | ริชาร์ด เจมส์ ฮาว |
ลิขสิทธิ์ | 2013-2019 ริชาร์ด ฮาว |
ใบอนุญาต | เอ็มไอที/แอลจีพีแอล |
อีเมล | [email protected] |
โปรเจ็กต์นี้ใช้คอมพิวเตอร์สแต็กขนาดเล็กที่ออกแบบมาเพื่อเรียกใช้งาน Forth โดยใช้ CPU J1 โปรเซสเซอร์ได้รับการเขียนใหม่ใน VHDL จาก Verilog และขยายออกไปเล็กน้อย
เป้าหมายของโครงการมีดังนี้:
เรียบร้อยแล้วทั้ง 3 รายการ
โปรเซสเซอร์ H2 เช่นเดียวกับ J1 คือโปรเซสเซอร์แบบสแต็กที่ดำเนินการชุดคำสั่งซึ่งเหมาะอย่างยิ่งสำหรับ FORTH
เป้าหมายปัจจุบันคือบอร์ด Nexys3 ซึ่งมี Xilinx Spartan-6 XC6LX16-CS324 FPGA บอร์ดใหม่จะถูกกำหนดเป้าหมายในอนาคตเนื่องจากบอร์ดนี้กำลังจะหมดอายุการใช้งาน VHDL ถูกเขียนในลักษณะทั่วไป โดยมีการอนุมานส่วนประกอบฮาร์ดแวร์แทนการสร้างอินสแตนซ์อย่างชัดเจน ซึ่งควรทำให้โค้ดสามารถพกพาได้สะดวก แม้ว่าอินเทอร์เฟซไปยังส่วนประกอบของบอร์ด Nexys3 จะเฉพาะกับอุปกรณ์ต่อพ่วงบนบอร์ดนั้น
ดูวิดีโอการทำงานของโครงการบนฮาร์ดแวร์ได้ที่นี่:
SoC ยังสามารถจำลองด้วยตัวจำลองที่เขียนด้วยภาษา C ดังที่แสดงด้านล่าง:
สถาปัตยกรรมระบบมีดังนี้:
ใบอนุญาตที่ใช้โดยโครงการเป็นแบบผสมและเป็นแบบต่อไฟล์ สำหรับรหัสของฉัน ฉันใช้ใบอนุญาต MIT - ดังนั้นอย่าลังเลที่จะใช้มันตามที่คุณต้องการ ใบอนุญาตอื่นๆ ที่ใช้คือใบอนุญาต LGPL และ Apache 2.0 ซึ่งจำกัดอยู่ในโมดูลเดียว ดังนั้นคุณจึงสามารถลบออกได้หากคุณไม่ชอบโค้ด LGPL
บอร์ดเป้าหมายเดียวที่มีอยู่ในขณะนี้คือ Nexys3 ซึ่งควรเปลี่ยนในอนาคตเนื่องจากบอร์ดอยู่ในจุดสิ้นสุดของชีวิต บอร์ดถัดไปที่ฉันต้องการสนับสนุนคือบอร์ดรุ่นต่อจาก Nexys 4 และ myStorm BlackIce (https://mystorm.uk/) บอร์ด myStorm ใช้ toolchain แบบโอเพ่นซอร์สอย่างสมบูรณ์สำหรับการสังเคราะห์ วางและเส้นทาง และการสร้างไฟล์บิต
โครงสร้างได้รับการทดสอบภายใต้ Debian Linux เวอร์ชัน 8
คุณจะต้องการ:
ฮาร์ดแวร์:
Xilinx ISE สามารถ (หรืออาจ) ดาวน์โหลดได้ฟรี แต่ต้องลงทะเบียน ISE จะต้องอยู่ในเส้นทางของคุณ:
PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;
PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;
ในการสร้าง toolchain ที่ใช้ C:
make embed.hex
วิธีสร้างไฟล์บิตที่สามารถแฟลชไปยังบอร์ดเป้าหมายได้:
make simulation synthesis implementation bitfile
วิธีอัปโหลดบิตไฟล์ไปยังบอร์ดเป้าหมาย:
make upload
หากต้องการดูรูปแบบคลื่นที่สร้างโดย "สร้างการจำลอง":
make viewer
ตัวจำลอง CLI ที่ใช้ C สามารถเรียกใช้ได้ด้วย:
make run
ซึ่งจะประกอบไฟล์ต้นฉบับ H2 Forth embed.fth และเรียกใช้ไฟล์อ็อบเจ็กต์ที่ประกอบภายใต้เครื่องจำลอง H2 โดยที่เปิดใช้งานดีบักเกอร์ โปรแกรมจำลองกราฟิกสามารถรันด้วย:
make gui-run
ซึ่งต้องใช้ freeglut เช่นเดียวกับคอมไพเลอร์ C
โครงการ J1 ดั้งเดิมสามารถดูได้ที่:
โปรเจ็กต์นี้กำหนดเป้าหมายไปที่คอร์ J1 ดั้งเดิมและจัดเตรียมการใช้งาน eForth (เขียนโดยใช้ Gforth สำหรับการคอมไพล์เมตาดาต้า/การคอมไพล์ข้ามไปยังคอร์ J1) นอกจากนี้ยังมีตัวจำลองสำหรับระบบที่เขียนด้วยภาษาซี
สามารถดูล่าม eForth ซึ่งสร้างเมตาคอมไพเลอร์ได้ที่:
ขณะนี้โปรเซสเซอร์ H2 และอุปกรณ์ต่อพ่วงที่เกี่ยวข้องค่อนข้างเสถียรแล้ว อย่างไรก็ตาม แหล่งที่มาจะเป็นแนวทางที่ชัดเจนเกี่ยวกับวิธีการทำงานของคำสั่งและอุปกรณ์ต่อพ่วงตลอดจนแผนผังการลงทะเบียน
มีการปรับเปลี่ยนเล็กน้อยใน CPU J1 ซึ่งรวมถึง:
CPU H2 มีพฤติกรรมคล้ายกับ CPU J1 มาก และสามารถอ่าน J1 PDF ได้เพื่อให้เข้าใจโปรเซสเซอร์นี้ได้ดีขึ้น โปรเซสเซอร์เป็นแบบ 16 บิตพร้อมคำสั่งให้ใช้รอบสัญญาณนาฬิกาเดียว คำ Forth ดั้งเดิมส่วนใหญ่สามารถดำเนินการได้ในรอบเดียวเช่นกัน ข้อยกเว้นที่น่าสังเกตประการหนึ่งคือ store ("!") ซึ่งแบ่งออกเป็นสองคำสั่ง
CPU มีสถานะต่อไปนี้อยู่ภายใน:
โหลดและจัดเก็บลงในบล็อก RAM ที่เก็บโปรแกรม H2 ทิ้งบิตต่ำสุด การดำเนินการหน่วยความจำอื่นๆ ทุกครั้งจะใช้บิตที่ต่ำกว่า (เช่น การข้ามและโหลด และจัดเก็บไปยังอุปกรณ์ต่อพ่วงอินพุต/เอาท์พุต) เพื่อให้แอปพลิเคชันสามารถใช้บิตต่ำสุดสำหรับการทำงานของอักขระเมื่อเข้าถึง RAM ของโปรแกรม
ชุดคำสั่งถูกถอดรหัสในลักษณะดังต่อไปนี้:
+---------------------------------------------------------------+
| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------------------------------------------------------+
| 1 | LITERAL VALUE |
+---------------------------------------------------------------+
| 0 | 0 | 0 | BRANCH TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 0 | 1 | CONDITIONAL BRANCH TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 1 | 0 | CALL TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 1 | 1 | ALU OPERATION |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
+---------------------------------------------------------------+
| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------------------------------------------------------+
T : Top of data stack
N : Next on data stack
PC : Program Counter
LITERAL VALUES : push a value onto the data stack
CONDITIONAL : BRANCHS pop and test the T
CALLS : PC+1 onto the return stack
T2N : Move T to N
T2R : Move T to top of return stack
N2A : STORE T to memory location addressed by N
R2P : Move top of return stack to PC
RSTACK and DSTACK are signed values (twos compliment) that are
the stack delta (the amount to increment or decrement the stack
by for their respective stacks: return and data)
การดำเนินการ ALU ทั้งหมดจะแทนที่ T:
ค่า | การดำเนินการ | คำอธิบาย |
---|---|---|
0 | ต | ด้านบนของสแต็ค |
1 | เอ็น | คัดลอก T ถึง N |
2 | ที+เอ็น | ส่วนที่เพิ่มเข้าไป |
3 | ที แอนด์ เอ็น | ระดับบิตและ |
4 | ที หรือ เอ็น | บิตไวส์หรือ |
5 | ที ^ เอ็น | บิตไวซ์ XOR |
6 | ~ต | การผกผันแบบบิต |
7 | ที = น | การทดสอบความเท่าเทียมกัน |
8 | เอ็น < ต | ลงนามเปรียบเทียบ |
9 | น >> ต | การเลื่อนไปทางขวาแบบลอจิคัล |
10 | ที - 1 | ลดลง |
11 | ร | ด้านบนของกองส่งคืน |
12 | [ท] | โหลดจากที่อยู่ |
13 | ยังไม่มีข้อความ << ต | การเลื่อนไปทางซ้ายแบบลอจิคัล |
14 | ความลึก | ความลึกของกอง |
15 | ไม่นะ< T | การเปรียบเทียบที่ไม่ได้ลงนาม |
16 | ตั้งค่าสถานะ CPU | เปิดใช้งานการขัดจังหวะ |
17 | รับสถานะ CPU | มีการขัดจังหวะหรือไม่? |
18 | ความลึก | ความลึกของผลตอบแทน stk |
19 | 0= | ต == 0? |
20 | รหัสซีพียู | ตัวระบุซีพียู |
21 | ตัวอักษร | คำสั่งภายใน |
รีจิสเตอร์ที่ทำเครื่องหมายนำหน้าด้วย 'o' คือรีจิสเตอร์เอาต์พุต ส่วนรีจิสเตอร์ที่มีคำนำหน้า 'i' คือรีจิสเตอร์อินพุต รีจิสเตอร์จะถูกแบ่งออกเป็นส่วนอินพุตและเอาท์พุตของรีจิสเตอร์ และที่อยู่ของรีจิสเตอร์อินพุตและเอาท์พุตจะไม่สอดคล้องกันในทุกกรณี
อุปกรณ์ต่อพ่วงต่อไปนี้ถูกนำมาใช้ใน VHDL SoC เพื่อเชื่อมต่อกับอุปกรณ์บนบอร์ด Nexys3:
SoC ยังมีชุดการขัดจังหวะที่จำกัดซึ่งสามารถเปิดหรือปิดใช้งานได้
แผนที่การลงทะเบียนเอาท์พุท:
ลงทะเบียน | ที่อยู่ | คำอธิบาย |
---|---|---|
oUart | 0x4000 | ลงทะเบียน UART |
oVT100 | 0x4002 | การเขียนเทอร์มินัล VT100 |
oไฟ LED | 0x4004 | เอาท์พุท LED |
oTimerCtrl | 0x4006 | การควบคุมการจับเวลา |
oMemDout | 0x4008 | เอาต์พุตข้อมูลหน่วยความจำ |
oMemControl | 0x400A | การควบคุมหน่วยความจำ / ที่อยู่สูง |
oMemAddrLow | 0x400C | ที่อยู่หน่วยความจำ Lo |
o7SegLED | 0x400E | จอแสดงผล LED 7 ส่วน 4 x |
oIrcMask | 0x4010 | หน้ากากขัดจังหวะ CPU |
oUartBaudTx | 0x4012 | การตั้งค่านาฬิกา UART Tx Baud |
oUartBaudRx | 0x4014 | การตั้งค่านาฬิกา UART Rx Baud |
การลงทะเบียนอินพุต:
ลงทะเบียน | ที่อยู่ | คำอธิบาย |
---|---|---|
iUart | 0x4000 | ลงทะเบียน UART |
ไอวีที100 | 0x4002 | สถานะเทอร์มินัลและแป้นพิมพ์ PS/2 |
ไอสวิตช์ | 0x4004 | ปุ่มและสวิตช์ |
iTimerDin | 0x4006 | ค่าตัวจับเวลาปัจจุบัน |
iMemDin | 0x4008 | อินพุตข้อมูลหน่วยความจำ |
ควรอ่านคำอธิบายต่อไปนี้ของรีจิสเตอร์ตามลำดับและอธิบายวิธีการทำงานของอุปกรณ์ต่อพ่วงด้วย
UART ที่มีอัตรารับส่งข้อมูลและรูปแบบคงที่ (115200, 8 บิต, 1 บิตหยุด) มีอยู่บน SoC UART มี FIFO ความลึก 8 ทั้งในช่อง RX และ TX การควบคุมของ UART จะแบ่งออกเป็น oUart และ iUart
ในการเขียนค่าให้กับ UART ให้ยืนยัน TXWE พร้อมกับใส่ข้อมูลลงใน TXDO สามารถวิเคราะห์สถานะ FIFO ได้โดยดูที่การลงทะเบียน iUart
หากต้องการอ่านค่าจาก UART: สามารถตรวจสอบ iUart เพื่อดูว่ามีข้อมูลอยู่ใน FIFO หรือไม่ หากมีการยืนยัน RXRE ในการลงทะเบียน oUart ในรอบนาฬิกาถัดไป ข้อมูลจะปรากฏในการลงทะเบียน iUart
อัตรารับส่งข้อมูลของ UART สามารถเปลี่ยนแปลงได้โดยการสร้างโครงการ VHDL ขึ้นใหม่ ความยาวบิต บิตพาริตี และบิตหยุดสามารถเปลี่ยนแปลงได้ด้วยการแก้ไข uart.vhd เท่านั้น
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X |TXWE| X | X |RXRE| X | X | TXDO |
+-------------------------------------------------------------------------------+
TXWE: UART TX Write Enable
RXRE: UART RX Read Enable
TXDO: UART TX Data Output
อุปกรณ์ข้อความ VGA จำลองเทอร์มินัลซึ่งผู้ใช้สามารถพูดคุยด้วยโดยการเขียนไปยังรีจิสเตอร์ oVT100 รองรับฟังก์ชันย่อยของเทอร์มินัล VT100 อินเทอร์เฟซทำงานเหมือนกับการเขียนไปยัง UART โดยมีสัญญาณไม่ว่างและสัญญาณควบคุมเหมือนกัน อินพุตนำมาจากแป้นพิมพ์ PS/2 ที่มีอยู่บนบอร์ด ซึ่งจะทำงานเหมือนกับกลไก RX ของ UART
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X |TXWE| X | X |RXRE| X | X | TXDO |
+-------------------------------------------------------------------------------+
TXWE: VT100 TX Write Enable
RXRE: UART RX Read Enable
TXDO: UART TX Data Output
บนบอร์ด Nexys3 มีกลุ่มไฟ LED อยู่ข้างๆ สวิตช์ ไฟ LED เหล่านี้สามารถเปิด (1) หรือปิด (0) ได้โดยการเขียนไปที่ LEDO LED แต่ละตัวที่นี่ตรงกับสวิตช์ที่อยู่ถัดไป
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | X | X | X | X | X | LEDO |
+-------------------------------------------------------------------------------+
LEDO: LED Output
ตัวจับเวลาสามารถควบคุมได้โดยการลงทะเบียน oTimerCtrl ซึ่งเป็นตัวจับเวลา 13 บิตที่ทำงานที่ 100MHz สามารถเลือกสร้างอินเทอร์รัปต์ได้ และสามารถอ่านจำนวนภายในตัวจับเวลาปัจจุบันกลับเข้ามาได้ด้วยรีจิสเตอร์ iTimerDin
ตัวจับเวลาจะนับเมื่อมีการยืนยันบิต TE เมื่อตัวจับเวลาถึงค่า TCMP มันจะพันรอบและสามารถสร้างการขัดจังหวะโดยการยืนยัน INTE นอกจากนี้ยังสลับบรรทัด Q และ NQ ที่ออกมาจากตัวจับเวลาและถูกส่งไปยังพินบนกระดาน (ดูไฟล์ข้อจำกัด top.ucf สำหรับพิน)
สามารถรีเซ็ตตัวจับเวลาได้โดยการเขียนไปที่ RST
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| TE | RST|INTE| TCMP |
+-------------------------------------------------------------------------------+
TE: Timer Enable
RST: Timer Reset
INTE: Interrupt Enable
TCMP: Timer Compare Value
แกน H2 มีกลไกในการขัดจังหวะ ต้องเปิดหรือปิดการขัดจังหวะด้วยคำสั่ง การขัดจังหวะแต่ละครั้งสามารถปกปิดได้เล็กน้อยใน IMSK เพื่อเปิดใช้งานการขัดจังหวะเฉพาะนั้น เลข '1' ใน IMSK เล็กน้อยเปิดใช้งานการขัดจังหวะเฉพาะนั้น ซึ่งจะถูกส่งไปยัง CPU หากมีการเปิดใช้งานการขัดจังหวะภายใน
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | X | X | X | X | X | IMSK |
+-------------------------------------------------------------------------------+
IMSK: Interrupt Mask
รีจิสเตอร์นี้ใช้เพื่อตั้งค่าบอดและความถี่นาฬิกาตัวอย่างสำหรับการส่งสัญญาณเท่านั้น
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| BTXC |
+-------------------------------------------------------------------------------+
BTXC: Baud Clock Settings
รีจิสเตอร์นี้ใช้เพื่อตั้งค่าบอดและความถี่นาฬิกาตัวอย่างสำหรับการรับสัญญาณเท่านั้น
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| BRXC |
+-------------------------------------------------------------------------------+
BRXC: Baud Clock Settings
ข้อมูลที่จะส่งออกไปยังที่อยู่ที่เลือกเมื่อเปิดใช้งานการเขียน (WE) ที่ออกใน oMemControl
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Data Ouput |
+-------------------------------------------------------------------------------+
รีจิสเตอร์นี้มีรีจิสเตอร์ควบคุมสำหรับหน่วยความจำออนบอร์ดบนบอร์ด Nexys3 บอร์ดประกอบด้วยอุปกรณ์หน่วยความจำสามตัว อุปกรณ์หน่วยความจำแบบไม่ลบเลือนสองตัว และอุปกรณ์ที่ใช้ RAM หนึ่งตัว อุปกรณ์ทั้งสองที่สามารถเข้าถึงได้โดยอินเทอร์เฟซ SRAM แบบธรรมดา (M45W8MW16 หนึ่งตัวที่ระเหยได้หนึ่งตัว และแบบไม่ลบเลือนหนึ่งตัว - NP8P128A13T1760E) สามารถเข้าถึงได้ทั้งคู่ อุปกรณ์ตัวที่สามเป็นอุปกรณ์หน่วยความจำแบบ SPI NP5Q128A13ESFC0E) และขณะนี้ยังไม่สามารถเข้าถึงได้
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| OE | WE | RST|WAIT| RCS| FCS| Address Hi |
+-------------------------------------------------------------------------------+
OE: Output Enable - enable reading from current address into iMemDin
WE: Write Enable - enable writing oMemDout into ram at current address
RST: Reset the Flash memory controller
RCS: RAM Chip Select, Enable Volatile Memory
FCS: Flash Chip Select, Enable Non-Volatile Memory
Address Hi: High Bits of RAM address
OE และ WE เป็นแบบเอกสิทธิ์เฉพาะบุคคล หากตั้งค่าทั้งสองอย่างไว้แล้วจะไม่มีผลกระทบใดๆ
ตัวควบคุมหน่วยความจำอยู่ในระหว่างการพัฒนา และอินเทอร์เฟซของตัวควบคุมอาจมีการเปลี่ยนแปลง
นี่คือบิตที่อยู่ด้านล่างของ RAM
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Address Lo |
+-------------------------------------------------------------------------------+
บนบอร์ด Nexys3 มีจอแสดงผล 7 ส่วนพร้อมจุดทศนิยม (จริงๆ แล้ว 8 ส่วน) ซึ่งสามารถใช้สำหรับเอาต์พุตตัวเลขได้ ส่วน LED ไม่สามารถระบุได้โดยตรง แต่ค่าที่เก็บไว้ใน L8SD จะถูกแมปกับค่าการแสดงผลเลขฐานสิบหก (หรือค่า BCD แต่ต้องใช้การสร้าง SoC ใหม่และการแก้ไขค่าทั่วไปใน VHDL)
ค่า '0' สอดคล้องกับศูนย์ที่แสดงบนส่วนของ LED, '15' ถึง 'F' ฯลฯ
มีจอแสดงผล 4 จอติดต่อกัน
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| L7SD0 | L7SD1 | L7SD2 | L7SD3 |
+-------------------------------------------------------------------------------+
L7SD0: LED 7 Segment Display (leftmost display)
L7SD1: LED 7 Segment Display
L7SD2: LED 7 Segment Display
L7SD3: LED 7 Segment Display (right most display)
การลงทะเบียน iUart ทำงานร่วมกับการลงทะเบียน oUart สถานะของ FIFO ที่บัฟเฟอร์ทั้งการส่งและรับไบต์จะมีอยู่ในรีจิสเตอร์ iUart เช่นเดียวกับไบต์ที่ได้รับใดๆ
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X |TFFL|TFEM| X |RFFL|RFEM| RXDI |
+-------------------------------------------------------------------------------+
TFFL: UART TX FIFO Full
TFEM: UART TX FIFO Empty
RFFL: UART RX FIFO Full
RFEM: UART RX FIFO Empty
RXDI: UART RX Data Input
รีจิสเตอร์ iVT100 ทำงานร่วมกับรีจิสเตอร์ oVT100 สถานะของ FIFO ที่บัฟเฟอร์ทั้งการส่งและรับไบต์มีอยู่ในรีจิสเตอร์ iVT100 เช่นเดียวกับไบต์ที่ได้รับใดๆ มันทำงานเหมือนกับการลงทะเบียน iUart/oUart
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X |TFFL|TFEM| X |RFFL|RFEM| 0 | ACHR |
+-------------------------------------------------------------------------------+
TFFL: VGA VT100 TX FIFO Full
TFEM: VGA VT100 TX FIFO Empty
RFFL: PS2 VT100 RX FIFO Full
RFEM: PS2 VT100 RX FIFO Empty
ACHR: New character available on PS2 Keyboard
รีจิสเตอร์นี้ประกอบด้วยค่าปัจจุบันของตัวนับตัวจับเวลา
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | TCNT |
+-------------------------------------------------------------------------------+
TCNT: Timer Counter Value
iSwitches มีบรรทัดอินพุตจากหลายแหล่ง ปุ่มต่างๆ (BUP, BDWN, BLFT, BRGH และ BCNT) สอดคล้องกับ D-Pad บนบอร์ด Nexys3 สวิตช์ (TSWI) เป็นสวิตช์ที่กล่าวถึงใน oLeds โดยแต่ละตัวจะมีไฟ LED อยู่ข้างๆ
สวิตช์และปุ่มต่างๆ ได้รับการดีดเด้งในฮาร์ดแวร์แล้ว ดังนั้นจึงไม่จำเป็นต้องประมวลผลเพิ่มเติมเมื่ออ่านข้อมูลจากรีจิสเตอร์เหล่านี้
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | BUP|BDWN|BLFT|BRGH|BCNT| TSWI |
+-------------------------------------------------------------------------------+
BUP: Button Up
BDWN: Button Down
BLFT: Button Left
BRGH: Button Right
BCNT: Button Center
TSWI: Two Position Switches
อินพุตหน่วยความจำ จาก SRAM หรือ Flash จัดทำดัชนีโดย oMemControl และ oMemAddrLow เมื่ออ่านจากแฟลช นี่อาจเป็นข้อมูลสถานะหรือข้อมูลจากตารางแบบสอบถาม
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Data Input |
+-------------------------------------------------------------------------------+
รูทีนบริการขัดจังหวะต่อไปนี้ถูกกำหนดไว้:
ชื่อ | ตัวเลข | คำอธิบาย |
---|---|---|
ไม่มีเลย | 0 | ไม่ได้ใช้ |
isrRxFifoNotEmpty | 1 | UART RX FIFO ไม่ว่างเปล่า |
isrRxFifoFull | 2 | UART RX FIFI เต็มแล้ว |
isrTxFifoNotEmpty | 3 | UART TX FIFO ไม่ว่างเปล่า |
isrTxFifoFull | 4 | UART TX FIFO เต็ม |
isrKbdNew | 5 | ตัวละครคีย์บอร์ด PS/2 ใหม่ |
isrTimer | 6 | เครื่องนับเวลา |
isrDPadButton | 7 | สถานะการเปลี่ยนปุ่ม D-Pad ใด ๆ |
เมื่อมีการขัดจังหวะเกิดขึ้น และเปิดใช้งานการขัดจังหวะภายในโปรเซสเซอร์ จากนั้นจะมีการเรียกไปยังตำแหน่งในหน่วยความจำ - ตำแหน่งจะเหมือนกับหมายเลข ISR ISR ที่มีตัวเลข '4' จะทำการโทร (ไม่ใช่การข้าม) ไปยังตำแหน่ง '4' ภายในหน่วยความจำ เป็นต้น
การขัดจังหวะมีเวลาแฝงอย่างน้อย 4-5 รอบก่อนที่จะดำเนินการ มีความล่าช้าสองถึงสามรอบในตัวจัดการคำขอขัดจังหวะ จากนั้นจะต้องทำการเรียกไปยังตำแหน่ง ISR ในหน่วยความจำ จากนั้นจึงทำการเรียกไปยัง คำที่ใช้ ISR นั้นเอง
หากการขัดจังหวะสองครั้งเกิดขึ้นพร้อมกัน ระบบจะประมวลผลจากหมายเลขขัดจังหวะต่ำสุดไปสูงสุด
การขัดจังหวะจะหายไปเมื่อมีการขัดจังหวะด้วยหมายเลขเดียวกันซึ่งยังไม่ได้รับการประมวลผล
ตัวแยกชิ้นส่วนและตัวจำลองที่ใช้ C สำหรับ H2 อยู่ในโปรแกรมเดียว (ดู h2.c) ตัวจำลองนี้ช่วยเสริมม้านั่งทดสอบ VHDL tb.vhd และไม่สามารถทดแทนได้ เมตาคอมไพเลอร์ทำงานบนล่าม eForth และมีอยู่ในไฟล์ embed.c และ embed.blk meta-compiler (สำนวน Forth สำหรับ cross-compiler) เป็นโปรแกรม Forth ซึ่งใช้เพื่อสร้างอิมเมจ eForth ที่ทำงานบนเป้าหมาย
Toolchain ในปัจจุบันอยู่ในช่วงฟลักซ์ ในอนาคตมีแนวโน้มที่จะบูรณาการได้มากขึ้นระหว่าง h2.c และ embed.c พร้อมกับการเปลี่ยน Embed Virtual Machine ให้เป็นเครื่องที่มีลักษณะคล้ายกับ CPU H2 มากขึ้น โดยมีเป้าหมายระยะยาวในการสร้างการโฮสต์ด้วยตนเอง ระบบ.
ในการสร้างทั้งสองอย่าง จำเป็นต้องมีคอมไพเลอร์ C เป้าหมายบิลด์ "h2" จะสร้างไฟล์ปฏิบัติการ h2 และ "embed" จะสร้างเมตาคอมไพเลอร์:
make h2 embed
และสามารถรันบนไฟล์ต้นฉบับ embed.fth โดยมีเป้าหมาย make:
make run
ไม่จำเป็นต้องใช้ไฟล์ make:
Linux:
cc -std=c99 h2.c -o h2 # To build the h2 executable
cc -std=c99 embed.c -o embed # To build the embed VM executable
./embed embed.blk embed.hex embed.fth # Create the target eForth image
./h2 -h # For a list of options
./h2 -r embed.hex # Run the assembled file
Windows:
gcc -std=c99 h2.c -o h2.exe # Builds the h2.exe executable
gcc -std=c99 embed.c -o embed.exe # Builds the embed.exe executable
embed.exe embed.blk embed.hex embed.fth # Create the target eForth iamge
h2.exe -h # For a list of options
h2.exe -r embed.hex # Run the assembled file
รายการตัวเลือกบรรทัดคำสั่งที่มีให้:
- stop processing options, following arguments are files
-h print a help message and exit
-v increase logging level
-d disassemble input files (default)
-D full disassembly of input files
-T Enter debug mode when running simulation
-r run hex file
-L # load symbol file
-s # number of steps to run simulation (0 = forever)
-n # specify NVRAM block file (default is nvram.blk)
file* file to process
โปรแกรมนี้เผยแพร่ภายใต้ลิขสิทธิ์ MIT คุณสามารถใช้งานและแก้ไขได้ตามต้องการ หากมีการปรับเปลี่ยนเพียงเล็กน้อย ก็ควรจะสามารถประกอบโปรแกรมสำหรับคอร์ J1 ดั้งเดิมได้
เมตาคอมไพเลอร์ทำงานบนเครื่องเสมือนแบบฝัง ซึ่งเป็นเครื่องเสมือน 16 บิตที่สืบทอดมาจาก CPU H2 โปรเจ็กต์นี้มีรูปแบบการรวบรวมเมตาที่อนุญาตให้อิมเมจ eForth สร้างอิมเมจ eForth ใหม่พร้อมการแก้ไข ระบบนั้นได้รับการดัดแปลงเพื่อใช้กับ H2 ซึ่งแทนที่ cross-compiler ที่เขียนด้วยภาษา C ซึ่งอนุญาตให้สร้างอิมเมจแรกสำหรับ H2 ได้
เมตาคอมไพเลอร์เป็นโปรแกรม Forth ธรรมดา ซึ่งมีอยู่ภายใน embed.fth จากนั้นโปรแกรม meta-compiler Forth จะถูกนำมาใช้เพื่อสร้างอิมเมจ eForth ที่สามารถทำงานบนเป้าหมาย H2
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการคอมไพล์เมตาใน Forth โปรดดู:
ตัวแยกส่วนรับไฟล์ข้อความที่มีโปรแกรมประกอบซึ่งประกอบด้วยเลขฐานสิบหก 16 บิต จากนั้นจะพยายามแยกชิ้นส่วนคำแนะนำ นอกจากนี้ยังสามารถป้อนไฟล์สัญลักษณ์ซึ่งแอสเซมเบลอร์สามารถสร้างได้และพยายามค้นหาตำแหน่งที่กระโดดและการโทรชี้ไป
ตัวแยกชิ้นส่วนถูกใช้โดยสคริปต์ tcl ที่เรียกโดย GTKwave โดยจะเปลี่ยนการติดตามคำสั่งของ H2 จากชุดตัวเลขไปเป็นคำสั่งและปลายทางสาขาที่พวกมันเป็นตัวแทน ทำให้การดีบัก VHDL ง่ายขึ้นมาก
รอยสีม่วงแสดงคำแนะนำในการถอดประกอบ
ตัวจำลองใน C ใช้คอร์ H2 และ SoC ส่วนใหญ่ IO สำหรับเครื่องจำลองนั้นไม่ถูกต้องตามรอบ แต่สามารถใช้สำหรับการรันและดีบักโปรแกรมด้วยผลลัพธ์ที่คล้ายกับการทำงานของฮาร์ดแวร์มาก ซึ่งเร็วกว่าการสร้างไฟล์บิตที่ใช้ในการแฟลช FPGA ขึ้นมาใหม่มาก
ตัวจำลองยังมีดีบักเกอร์ซึ่งได้รับการออกแบบให้คล้ายกับโปรแกรม DEBUG.COM ที่มีอยู่ใน DOS สามารถใช้ดีบักเกอร์เพื่อแยกส่วนของหน่วยความจำ ตรวจสอบสถานะของอุปกรณ์ต่อพ่วง และดัมพ์ส่วนของหน่วยความจำไปที่หน้าจอ นอกจากนี้ยังสามารถใช้เพื่อตั้งค่าเบรกพอยต์ ขั้นตอนเดียว และรันโค้ดจนกว่าจะถึงเบรกพอยต์
ในการรันดีบักเกอร์ต้องระบุไฟล์ hex หรือไฟล์ต้นฉบับ:
# -T turns debugging mode on
./h2 -T -r file.hex # Run simulator
โหมดการทำงานทั้งสองโหมดสามารถเพิ่มได้ด้วยไฟล์สัญลักษณ์ ซึ่งจะแสดงรายการตำแหน่งตัวแปร ป้ายกำกับ และฟังก์ชันที่มีแกนประกอบ
เมื่อได้รับตัวเลือก "-T" โหมดแก้ไขข้อบกพร่องจะถูกป้อนก่อนที่จะดำเนินการจำลอง ข้อความควรปรากฏขึ้นและบรรทัดคำสั่งควรมีลักษณะดังนี้:
$ ./h2 -T -R h2.fth
Debugger running, type 'h' for a list of command
debug>
จุดพักสามารถตั้งค่าได้ทั้งเชิงสัญลักษณ์หรือตามตำแหน่งของโปรแกรม คำสั่ง 'b' ใช้เพื่อตั้งค่าจุดพัก:
สามารถป้อนตัวเลขเป็นฐานแปด (นำหน้าตัวเลขด้วย '0') เลขฐานสิบหก (นำหน้าด้วย '0x') หรือเป็นทศนิยม ตามตัวอย่าง คำสั่งดีบักสามคำสั่งต่อไปนี้จะตั้งค่าเบรกพอยต์ไว้ที่ตำแหน่งเดียวกัน:
debug> b 16
debug> b 0x10
debug> b 020
'k' สามารถใช้เพื่อแสดงรายการจุดพักปัจจุบันที่ตั้งค่าไว้:
debug> k
0x0010
สิ่งนี้จะตั้งค่าเบรกพอยต์เมื่อฟังก์ชัน "key?" ถูกเรียกว่า:
debug> b key?
สามารถหยุดทั้งฟังก์ชันและเลเบลได้ โดยต้องใช้ไฟล์สัญลักษณ์ที่ระบุในบรรทัดคำสั่ง หรือประกอบและรันเพื่อใช้ในไฟล์ต้นฉบับ ไม่ใช่ไฟล์ hex ไฟล์สัญลักษณ์สามารถใช้กับไฟล์ต้นฉบับหรือไฟล์ฐานสิบหกได้
ในขั้นตอนเดียว คุณสามารถกำหนดคำสั่ง 's' ได้ แม้ว่าจะไม่เกิดขึ้นมากนักหากการติดตามถูกปิด (การติดตามถูกปิดโดยค่าเริ่มต้น) การติดตามสามารถเปิดหรือปิดได้ด้วยคำสั่ง 't':
debug> s
debug> s
debug> t
trace on
debug> s
0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init
debug> s
0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a
debug> s
0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004
ขอแนะนำให้ปิดการติดตามเมื่อรันการออกคำสั่ง 'c' หรือดำเนินการต่อ
'.' คำสั่งสามารถใช้เพื่อแสดงสถานะภายในแกน H2:
debug> .
Return Stack:
0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167
0167 0167
0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000
Variable Stack:
tos: 0000
0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000
0000 0000
0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000
pc: 0538
rp: 0001
dp: 0000
ie: false
และคำสั่ง 'p' สามารถใช้เพื่อแสดงสถานะของอุปกรณ์ต่อพ่วงจำลอง:
debug> p
LEDS: 00
VGA Cursor: 0005
VGA Control: 007a
Timer Control: 8032
Timer: 001b
IRC Mask: 0000
UART Input: 6c
LED 7seg: 0005
Switches: 00
LFSR: 40ba
Waiting: false
หากต้องการดูรายการคำสั่งทั้งหมด ให้ใช้คำสั่ง 'h'
วิธีอื่นๆ ในการเข้าสู่โหมดแก้ไขข้อบกพร่อง ได้แก่ การใส่คำสั่งแอสเซมเบลอร์ ".break" ลงในซอร์สโค้ด (ใช้งานได้เฉพาะในกรณีที่ใช้คำสั่งแอสเซมบลีและรันกับไฟล์ต้นฉบับ ไม่ใช่ในไฟล์ hex) และการกดปุ่มอักขระ Escape เมื่อเครื่องจำลองเปิดอยู่ พยายามอ่านข้อมูลผ่านแป้นพิมพ์ UART หรือ PS/2 จำลอง (การหลบหนีจะยังคงถูกส่งผ่านไปยังเครื่องจำลอง แต่จะเปิดใช้งานโหมดแก้ไขข้อบกพร่องด้วย)
โปรแกรมแยกต่างหากสามารถคอมไพล์ทดสอบภายใต้ Linux และ Windows สิ่งนี้จะจำลองอุปกรณ์ต่อพ่วงบอร์ด Nexys3 ที่อินเทอร์เฟซ SoC ด้วย แต่ให้สภาพแวดล้อมแบบกราฟิก ซึ่งแตกต่างจากยูทิลิตี้บรรทัดคำสั่ง การโต้ตอบกับอุปกรณ์และดูว่ามันกำลังทำอะไรอยู่นั้นง่ายกว่า แต่เซสชันการแก้ไขจุดบกพร่องนั้นได้รับการควบคุมน้อยกว่า มันต้องใช้จำนวนที่มากเกินไป
ด้านล่างนี้คือภาพของเซสชันที่ทำงานอยู่ในโปรแกรมจำลอง GUI:
การก่อสร้างสามารถทำได้ด้วย
make gui
และทำงานอยู่:
make gui-run
หรือ:
./gui h2.hex (on Linux)
gui.exe h2.hex (on Windows)
บิลด์ Linux ควรใช้งานได้เมื่อมีการติดตั้งแพ็คเกจการพัฒนาสำหรับจำนวนที่มากเกินไปบนระบบของคุณ บิลด์ Windows อาจต้องมีการเปลี่ยนแปลงระบบบิลด์และ/หรือการติดตั้งคอมไพเลอร์ ไลบรารี และส่วนหัวด้วยตนเอง
แผนที่หลักปัจจุบันคือ:
Up Activate Up D-Pad Button, Release turns off
Down Activate Down D-Pad Button, Release turns off
Left Activate Left D-Pad Button, Release turns off
Right Activate Right D-Pad Button, Release turns off
F1 - F8 Toggle Switch On/Off, F1 is left most, F8 Right Most
F11 Toggle UART/PS2 Keyboard Input
F12 Toggle Debugging Information
Escape Quit simulator
ปุ่มแป้นพิมพ์อื่นๆ ทั้งหมดจะเปลี่ยนเส้นทางไปยังอินพุตแป้นพิมพ์ UART หรือ PS/2
สามารถคลิกปุ่มสวิตช์และ D-Pad เพื่อเปิดสวิตช์ สวิตช์จะเปิดด้วยการคลิกซ้าย และปิดด้วยการคลิกขวา ปุ่ม D-Pads จะเปิดขึ้นด้วยการคลิกที่ด้านบนของปุ่ม และปิดด้วยการกดปุ่มที่ใดก็ได้บนหน้าจอ
ส่วนประกอบ VHDL ที่ใช้ในระบบนี้ได้รับการออกแบบให้สามารถนำกลับมาใช้ใหม่และพกพาได้ผ่านกลุ่มเครื่องมือและผู้ขายต่างๆ ส่วนประกอบฮาร์ดแวร์ เช่น บล็อก RAM จะถูกอนุมานและไม่ได้สร้างอินสแตนซ์อย่างชัดเจน ส่วนประกอบต่างๆ ได้รับการจัดทำให้เป็นแบบทั่วไปที่สุดเท่าที่จะเป็นไปได้ โดยส่วนใหญ่จะมีความกว้างที่เลือกได้ สิ่งนี้อาจถึงขั้นรุนแรง แต่น่าเสียดายที่ผู้จำหน่ายหลายรายยังไม่รองรับมาตรฐาน VHDL-2008
ไฟล์ | ใบอนุญาต | ผู้เขียน | คำอธิบาย |
---|---|---|---|
util.vhd | เอ็มไอที | ริชาร์ด เจ ฮาว | คอลเลกชันของส่วนประกอบทั่วไป |
h2.vhd | เอ็มไอที | ริชาร์ด เจ ฮาว | H2 Forth CPU Core |
uart.vhd | เอ็มไอที | ริชาร์ด เจ ฮาว | UART TX/RX (ปรับแต่งรันไทม์ได้) |
vga.vhd | LGPL3.0 | ฮาเวียร์ วี การ์เซีย | โหมดข้อความ จอแสดงผล VGA 80x40 |
ริชาร์ด เจ ฮาว | (และเทอร์มินัลอีมูเลเตอร์ VT100) | ||
kbd.vhd | - | สกอตต์ ลาร์สัน | แป้นพิมพ์ PS/2 |
ภาษาหลอก Forth ที่ใช้เป็นแอสเซมเบลอร์อธิบายไว้ข้างต้น แอปพลิเคชันที่ทำงานบน Forth core นั้นเป็นล่าม Forth ในตัวมันเอง ส่วนนี้อธิบายถึงล่าม Forth ที่ทำงานบน H2 Core ซึ่งมีอยู่ภายใน embed.fth
สิ่งที่ต้องทำ:
มีหลายภาษาที่ใช้ในโปรเจ็กต์นี้ ซึ่งทั้งหมดมีความแตกต่างกันอย่างสิ้นเชิง และจำเป็นต้องมีชุดมาตรฐานการเขียนโค้ดและแนวทางสไตล์ของตัวเอง
ชื่อสัญญาณทั่วไป:
clk - The system clock
rst - A reset signal for the module
we - Write Enable
re - Read Enable
di - Data In
din - Data In
do - Data Out
dout - Data Out
control - Generally an input to a register, the documentation
for the module will need to be consulted to find out
what each bit means
signal_we - The write enable for 'signal'
signal_i - This is an input signal
signal_o - This is an output signal
โดยทั่วไปจะไม่ใช้ส่วนต่อท้าย "_i" และ "_o" โมดูลจะถูกใช้ให้สั้นและเลือกชื่อเพื่อให้ความหมายชัดเจน กฎนี้อาจได้รับการทบทวนอีกครั้งเมื่อโครงการเติบโตขึ้น
ส่วนประกอบควร:
constant N: positive := 4;
signal a: std_logic_vector(N - 1 downto 0) := (others => '1');
แทน:
signal a: std_logic_vector(3 downto 0) := x"F";
กฎสไตล์มีดังนี้:
ตัวอย่างของแนวทางการจัดรูปแบบ ซึ่งจะอธิบายการลงทะเบียนความกว้างที่กำหนดเอง:
-- Lots of comments about what the unit does should go
-- here. Describe the waveforms, states and use ASCII
-- art where possible.
library ieee, work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- numeric_std not std_logic_arith
entity reg is -- generic and port indented one tab, their parameters two
generic (
N: positive); -- Generic parameters make for a generic component
port (
clk: in std_logic; -- standard signal names
rst: in std_logic; --
we: in std_logic;
di: in std_logic_vector(N - 1 downto 0);
do: out std_logic_vector(N - 1 downto 0)); -- note the position of ");
end entity; -- "end entity", not "end reg"
architecture rtl of reg is
signal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others => '0');
begin
do <= r_c;
process(rst, clk)
begin
if rst = '1' then -- asynchronous reset
r_c <= (others => '0');
elsif rising_edge(clk) then -- rising edge, not "clk'event and clk = '1'"
r_c <= r_n;
end if;
end process;
process(r_c, di, we)
begin
r_n <= r_c;
if we = '1' then
r_n <= di;
end if;
end process;
end; -- "end" or "end architecture"
มีโค้ด C ค่อนข้างมากที่ใช้ภายในโปรเจ็กต์นี้ ใช้เพื่อสร้างห่วงโซ่เครื่องมือสำหรับคอร์ H2 และเพื่อจำลองระบบ
ไม่มีอะไรน่าประหลาดใจเกินไปเกี่ยวกับโค้ด C ภายในนี้ ดังนั้นควรจัดการกับข้อยกเว้นบางประการ
static const char *alu_op_to_string(uint16_t instruction) {
/* notice also that the 'case' clauses are inline with the
* switch selector */
switch (ALU_OP(instruction)) {
case ALU_OP_T: return "T";
case ALU_OP_N: return "N";
case ALU_OP_T_PLUS_N: return "T+N";
case ALU_OP_T_AND_N: return "T&N";
case ALU_OP_T_OR_N: return "T|N";
case ALU_OP_T_XOR_N: return "T^N";
case ALU_OP_T_INVERT: return "~T";
case ALU_OP_T_EQUAL_N: return "N=T";
case ALU_OP_N_LESS_T: return "T>N";
case ALU_OP_N_RSHIFT_T: return "N>>T";
case ALU_OP_T_DECREMENT: return "T-1";
case ALU_OP_R: return "R";
case ALU_OP_T_LOAD: return "[T]";
case ALU_OP_N_LSHIFT_T: return "N<N";
case ALU_OP_ENABLE_INTERRUPTS: return "seti";
case ALU_OP_INTERRUPTS_ENABLED: return "iset?";
case ALU_OP_RDEPTH: return "rdepth";
case ALU_OP_T_EQUAL_0: return "0=";
case ALU_OP_CPU_ID: return "cpu-id";
default: return "unknown";
}
}
if (foo)
bar();
else
baz();
picocom --omap delbs -b 115200 -e b /dev/ttyUSB1