From 129a1c975dbd0c042576010b1f6eb40d19fc5733 Mon Sep 17 00:00:00 2001 From: Vaino Kauppila Date: Sun, 19 Apr 2026 03:02:33 +0300 Subject: fix operand order of subtraction. add rollover counter UART test. --- Containerfile | 2 +- PIC/ALU.vhd | 13 +- PIC/prog_rom.vhd | 448 +++++++++++++++++++++++++------------------------- PIC/state_machine.vhd | 2 - PIC/test_uart.c | 55 +++++-- test_uart.hex | 61 ++++--- 6 files changed, 313 insertions(+), 268 deletions(-) diff --git a/Containerfile b/Containerfile index 635f5b4..347e3eb 100644 --- a/Containerfile +++ b/Containerfile @@ -9,7 +9,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libusb-1.0-0 \ make \ gcc \ - libc-dev \ + libc6-dev \ zlib1g-dev \ python3 \ python3-pip \ diff --git a/PIC/ALU.vhd b/PIC/ALU.vhd index ac770a6..b7c0344 100644 --- a/PIC/ALU.vhd +++ b/PIC/ALU.vhd @@ -78,7 +78,11 @@ architecture rtl of alu is end if; res <= t; if do_skip then - do_skip_out <= '1' when unsigned(t) = 0 else '0'; + if unsigned(t) = 0 then + do_skip_out <= '1'; + else + do_skip_out <= '0'; + end if; else stat <= set_flag(FLAG_Z, sel(unsigned(t) = 0, '1', '0'), stat_in); end if; @@ -117,10 +121,11 @@ begin result <= tmp_extended(7 downto 0); when SUBLW | SUBWF => - tmp_extended := std_logic_vector(unsigned('0' & a) - unsigned('0' & b)); + -- PIC16F84A: SUBWF = f - W, SUBLW = k - W → dest = b - a + tmp_extended := std_logic_vector(unsigned('0' & b) - unsigned('0' & a)); - -- DC - tmp(4 downto 0) := std_logic_vector(('0' & unsigned(a(3 downto 0))) - ('0' & unsigned(b(3 downto 0)))); + -- DC: borrow out of lower nibble + tmp(4 downto 0) := std_logic_vector(('0' & unsigned(b(3 downto 0))) - ('0' & unsigned(a(3 downto 0)))); tmp_status := set_flag(FLAG_Z, sel(unsigned(tmp_extended(7 downto 0)) = 0, '1', '0'), status_in); tmp_status := set_flag(FLAG_C, not tmp_extended(8), tmp_status); diff --git a/PIC/prog_rom.vhd b/PIC/prog_rom.vhd index 6ef8001..f3dcf64 100644 --- a/PIC/prog_rom.vhd +++ b/PIC/prog_rom.vhd @@ -17,14 +17,14 @@ architecture rtl of prog_rom is constant rom : rom_t := ( 0 => "00000000000000", 1 => "10100000000010", - 2 => "11000000011000", + 2 => "11000001101111", 3 => "00000010011010", 4 => "11000000000001", 5 => "00000010011011", 6 => "11000010000000", 7 => "00000000000000", 8 => "00000000000000", - 9 => "10000010011110", + 9 => "10000100010010", 10 => "00000000000000", 11 => "00000000000000", 12 => "01001010000011", @@ -32,7 +32,7 @@ architecture rtl of prog_rom is 14 => "00000010011101", 15 => "00100000011011", 16 => "00000010011100", - 17 => "11000000011010", + 17 => "11000001110001", 18 => "00000010011110", 19 => "11000000000001", 20 => "00000010011111", @@ -64,7 +64,7 @@ architecture rtl of prog_rom is 46 => "11000010000000", 47 => "00000000000000", 48 => "00000000000000", - 49 => "10000010011110", + 49 => "10000100010010", 50 => "00000000000000", 51 => "00000000000000", 52 => "01001010000011", @@ -79,7 +79,7 @@ architecture rtl of prog_rom is 61 => "11000010000000", 62 => "00000000000000", 63 => "00000000000000", - 64 => "10000010011110", + 64 => "10000100010010", 65 => "00000000000000", 66 => "00000000000000", 67 => "01001010000011", @@ -103,7 +103,7 @@ architecture rtl of prog_rom is 85 => "11000010000000", 86 => "00000000000000", 87 => "00000000000000", - 88 => "10000010011110", + 88 => "10000100010010", 89 => "00000000000000", 90 => "00000000000000", 91 => "01001010000011", @@ -134,7 +134,7 @@ architecture rtl of prog_rom is 116 => "11000010000000", 117 => "00000000000000", 118 => "00000000000000", - 119 => "10000010111111", + 119 => "10000100110011", 120 => "00000000000000", 121 => "00000000000000", 122 => "01001010000011", @@ -171,229 +171,229 @@ architecture rtl of prog_rom is 153 => "10100000010101", 154 => "00000000000000", 155 => "00000000000000", - 156 => "10100011010010", + 156 => "10100010011110", 157 => "00000000001000", - 158 => "11101000000000", - 159 => "01100100000011", - 160 => "10100010100110", - 161 => "11101010000000", - 162 => "01100100000011", - 163 => "10100010110000", - 164 => "00000110011011", - 165 => "11010000000000", - 166 => "00100000011010", - 167 => "00000010000100", - 168 => "01001110000011", - 169 => "01100000011011", - 170 => "01011110000011", - 171 => "00100000000000", - 172 => "00000010011011", - 173 => "00101010000100", - 174 => "00100000000000", - 175 => "00000000001000", - 176 => "00000000000000", - 177 => "00000000000000", - 178 => "10000011001101", - 179 => "00000010011001", - 180 => "00111110011010", - 181 => "00001110011011", - 182 => "00101010011011", - 183 => "00000000000000", - 184 => "00000000000000", - 185 => "10000011001101", - 186 => "00000010011000", - 187 => "00100000011001", - 188 => "00000010011011", - 189 => "00100000011000", - 190 => "00000000001000", - 191 => "11101000000000", - 192 => "01100100000011", - 193 => "10100011000110", - 194 => "11101010000000", - 195 => "01100100000011", - 196 => "10100011001101", - 197 => "11010000000000", - 198 => "00100000011010", - 199 => "00000010000100", - 200 => "01001110000011", - 201 => "01100000011011", - 202 => "01011110000011", - 203 => "00100000000000", - 204 => "00000000001000", - 205 => "00100000011011", - 206 => "00000010001010", - 207 => "00100000011010", - 208 => "00000010000010", - 209 => "00000000001000", - 210 => "11000000000000", - 211 => "00000010101111", - 212 => "11000011111101", - 213 => "00000010101110", - 214 => "11000010000000", - 215 => "00000010110000", - 216 => "00100000101110", - 217 => "00000010011010", - 218 => "00100000101111", - 219 => "00000010011011", - 220 => "00100000110000", - 221 => "00000010101100", - 222 => "00100000011011", - 223 => "00000010101011", - 224 => "00100000011010", - 225 => "00000010101010", - 226 => "00100000101010", - 227 => "00000010011010", - 228 => "00100000101011", - 229 => "00000010011011", - 230 => "00100000101100", - 231 => "10000010111111", - 232 => "00000010101101", - 233 => "00100000101101", - 234 => "01100100000011", - 235 => "10100011110100", - 236 => "00100000101101", - 237 => "10000100001111", - 238 => "00101010101010", - 239 => "01100100000011", - 240 => "00101010101011", - 241 => "01100100000011", - 242 => "00101010101100", - 243 => "10100011100010", - 244 => "01001010000011", - 245 => "00100001110010", - 246 => "00000010101110", - 247 => "01100010101110", - 248 => "10100011110100", - 249 => "00100001110001", - 250 => "10000100001111", - 251 => "10100011110100", - 252 => "00000000001000", - 253 => "11010001001000", - 254 => "11010001100101", - 255 => "11010001101100", - 256 => "11010001101100", - 257 => "11010001101111", - 258 => "11010000100000", - 259 => "11010001100110", - 260 => "11010001110010", - 261 => "11010001101111", - 262 => "11010001101101", - 263 => "11010000100000", - 264 => "11010001010000", - 265 => "11010001001001", - 266 => "11010001000011", - 267 => "11010000100001", - 268 => "11010000001101", - 269 => "11010000001010", - 270 => "11010000000000", - 271 => "00000010101000", - 272 => "01001010000011", - 273 => "00100001110010", - 274 => "00000010101001", - 275 => "01100000101001", - 276 => "10100100010000", - 277 => "00100000101000", - 278 => "00000011110000", - 279 => "00000000001000", - 280 => "11010000000001", + 158 => "00000110110101", + 159 => "11000000000001", + 160 => "00000010101111", + 161 => "11000001100111", + 162 => "00000010101110", + 163 => "11000010000000", + 164 => "00000010110000", + 165 => "00100000101110", + 166 => "00000010011010", + 167 => "00100000101111", + 168 => "00000010011011", + 169 => "00100000110000", + 170 => "10000101000110", + 171 => "11000001000011", + 172 => "10000101011110", + 173 => "11000000111010", + 174 => "10000101011110", + 175 => "00100000110101", + 176 => "00000010101110", + 177 => "00000110101111", + 178 => "11000011001000", + 179 => "00001000101110", + 180 => "01110000000011", + 181 => "10100011000000", + 182 => "11000000110010", + 183 => "10000101011110", + 184 => "00100000101110", + 185 => "00000010110000", + 186 => "11000000111000", + 187 => "00011100110000", + 188 => "00000010101110", + 189 => "11000000000001", + 190 => "00000010101111", + 191 => "10100011001101", + 192 => "11000001100100", + 193 => "00001000101110", + 194 => "01110000000011", + 195 => "10100011001101", + 196 => "11000000110001", + 197 => "10000101011110", + 198 => "00100000101110", + 199 => "00000010110000", + 200 => "11000010011100", + 201 => "00011100110000", + 202 => "00000010101110", + 203 => "11000000000001", + 204 => "00000010101111", + 205 => "11000000110000", + 206 => "00000010110000", + 207 => "11000000001010", + 208 => "00001000101110", + 209 => "01110000000011", + 210 => "10100011011010", + 211 => "00100000101110", + 212 => "00000010110001", + 213 => "11000011110110", + 214 => "00011100110001", + 215 => "00000010101110", + 216 => "00101010110000", + 217 => "10100011001111", + 218 => "00100000110000", + 219 => "00000010110001", + 220 => "00100000101111", + 221 => "01110100000011", + 222 => "10100011100011", + 223 => "00100000110000", + 224 => "11101000110000", + 225 => "01100100000011", + 226 => "10100011100101", + 227 => "00100000110001", + 228 => "10000101011110", + 229 => "00100000101110", + 230 => "00000010101111", + 231 => "11000000110000", + 232 => "00011100101111", + 233 => "00000010101110", + 234 => "10000101011110", + 235 => "11000000000001", + 236 => "00000010101111", + 237 => "11000001110111", + 238 => "00000010101110", + 239 => "11000010000000", + 240 => "00000010110000", + 241 => "00100000101110", + 242 => "00000010011010", + 243 => "00100000101111", + 244 => "00000010011011", + 245 => "00100000110000", + 246 => "10000101000110", + 247 => "00101010110101", + 248 => "00000110110010", + 249 => "00000110110011", + 250 => "00000110110100", + 251 => "00100000110100", + 252 => "00000010101000", + 253 => "00101000101000", + 254 => "00000010110100", + 255 => "00100000110100", + 256 => "01110100000011", + 257 => "10100011111011", + 258 => "00101000110011", + 259 => "00000010101000", + 260 => "00000010110011", + 261 => "00100000101000", + 262 => "11101000011110", + 263 => "01110100000011", + 264 => "10100011111010", + 265 => "00100000110010", + 266 => "00000010101000", + 267 => "00101000101000", + 268 => "00000010110010", + 269 => "11101001110100", + 270 => "01110100000011", + 271 => "10100011111001", + 272 => "10100010101011", + 273 => "00000000001000", + 274 => "11101000000000", + 275 => "01100100000011", + 276 => "10100100011010", + 277 => "11101010000000", + 278 => "01100100000011", + 279 => "10100100100100", + 280 => "00000110011011", 281 => "11010000000000", - 282 => "11010000100000", - 283 => "11010000000001", - 284 => "11010000110001", - 285 => "11010000000000", - 286 => "11010000000001", - 287 => "11010000000000", - 288 => "11010000000000", - 289 => "00000000000000", - 290 => "00000000000000", - 291 => "00000000000000", + 282 => "00100000011010", + 283 => "00000010000100", + 284 => "01001110000011", + 285 => "01100000011011", + 286 => "01011110000011", + 287 => "00100000000000", + 288 => "00000010011011", + 289 => "00101010000100", + 290 => "00100000000000", + 291 => "00000000001000", 292 => "00000000000000", 293 => "00000000000000", - 294 => "00000000000000", - 295 => "00000000000000", - 296 => "00000000000000", - 297 => "00000000000000", - 298 => "00000000000000", + 294 => "10000101000001", + 295 => "00000010011001", + 296 => "00111110011010", + 297 => "00001110011011", + 298 => "00101010011011", 299 => "00000000000000", 300 => "00000000000000", - 301 => "00000000000000", - 302 => "00000000000000", - 303 => "00000000000000", - 304 => "00000000000000", - 305 => "00000000000000", - 306 => "00000000000000", - 307 => "00000000000000", - 308 => "00000000000000", - 309 => "00000000000000", - 310 => "00000000000000", - 311 => "00000000000000", - 312 => "00000000000000", - 313 => "00000000000000", - 314 => "00000000000000", - 315 => "00000000000000", - 316 => "00000000000000", - 317 => "00000000000000", - 318 => "00000000000000", - 319 => "00000000000000", - 320 => "00000000000000", - 321 => "00000000000000", - 322 => "00000000000000", - 323 => "00000000000000", - 324 => "00000000000000", - 325 => "00000000000000", - 326 => "00000000000000", - 327 => "00000000000000", - 328 => "00000000000000", - 329 => "00000000000000", - 330 => "00000000000000", - 331 => "00000000000000", - 332 => "00000000000000", - 333 => "00000000000000", - 334 => "00000000000000", - 335 => "00000000000000", - 336 => "00000000000000", - 337 => "00000000000000", - 338 => "00000000000000", - 339 => "00000000000000", - 340 => "00000000000000", - 341 => "00000000000000", - 342 => "00000000000000", - 343 => "00000000000000", - 344 => "00000000000000", - 345 => "00000000000000", - 346 => "00000000000000", - 347 => "00000000000000", - 348 => "00000000000000", - 349 => "00000000000000", - 350 => "00000000000000", - 351 => "00000000000000", - 352 => "00000000000000", - 353 => "00000000000000", - 354 => "00000000000000", - 355 => "00000000000000", - 356 => "00000000000000", - 357 => "00000000000000", - 358 => "00000000000000", - 359 => "00000000000000", - 360 => "00000000000000", - 361 => "00000000000000", - 362 => "00000000000000", - 363 => "00000000000000", - 364 => "00000000000000", - 365 => "00000000000000", - 366 => "00000000000000", - 367 => "00000000000000", - 368 => "00000000000000", - 369 => "00000000000000", - 370 => "00000000000000", - 371 => "00000000000000", - 372 => "00000000000000", - 373 => "00000000000000", - 374 => "00000000000000", - 375 => "00000000000000", - 376 => "00000000000000", - 377 => "00000000000000", - 378 => "00000000000000", + 301 => "10000101000001", + 302 => "00000010011000", + 303 => "00100000011001", + 304 => "00000010011011", + 305 => "00100000011000", + 306 => "00000000001000", + 307 => "11101000000000", + 308 => "01100100000011", + 309 => "10100100111010", + 310 => "11101010000000", + 311 => "01100100000011", + 312 => "10100101000001", + 313 => "11010000000000", + 314 => "00100000011010", + 315 => "00000010000100", + 316 => "01001110000011", + 317 => "01100000011011", + 318 => "01011110000011", + 319 => "00100000000000", + 320 => "00000000001000", + 321 => "00100000011011", + 322 => "00000010001010", + 323 => "00100000011010", + 324 => "00000010000010", + 325 => "00000000001000", + 326 => "00000010101100", + 327 => "00100000011011", + 328 => "00000010101011", + 329 => "00100000011010", + 330 => "00000010101010", + 331 => "00100000101010", + 332 => "00000010011010", + 333 => "00100000101011", + 334 => "00000010011011", + 335 => "00100000101100", + 336 => "10000100110011", + 337 => "00000010101101", + 338 => "00100000101101", + 339 => "01100100000011", + 340 => "10100101011101", + 341 => "00100000101101", + 342 => "10000101011110", + 343 => "00101010101010", + 344 => "01100100000011", + 345 => "00101010101011", + 346 => "01100100000011", + 347 => "00101010101100", + 348 => "10100101001011", + 349 => "00000000001000", + 350 => "00000010101000", + 351 => "01001010000011", + 352 => "00100001110010", + 353 => "00000010101001", + 354 => "01100000101001", + 355 => "10100101011111", + 356 => "00100000101000", + 357 => "00000011110000", + 358 => "00000000001000", + 359 => "11010001001000", + 360 => "11010001100101", + 361 => "11010001101100", + 362 => "11010001101100", + 363 => "11010001101111", + 364 => "11010000001101", + 365 => "11010000001010", + 366 => "11010000000000", + 367 => "11010000000001", + 368 => "11010000000000", + 369 => "11010001111010", + 370 => "11010000000001", + 371 => "11010000110110", + 372 => "11010000000000", + 373 => "11010000000001", + 374 => "11010000000000", + 375 => "11010000001101", + 376 => "11010000001010", + 377 => "11010000000000", + 378 => "11010000000000", 379 => "00000000000000", 380 => "00000000000000", 381 => "00000000000000", diff --git a/PIC/state_machine.vhd b/PIC/state_machine.vhd index 464e0bc..24da581 100644 --- a/PIC/state_machine.vhd +++ b/PIC/state_machine.vhd @@ -119,8 +119,6 @@ begin re_mem <= '1'; end if; - - state <= Execute; when Execute => diff --git a/PIC/test_uart.c b/PIC/test_uart.c index f453e21..2656371 100644 --- a/PIC/test_uart.c +++ b/PIC/test_uart.c @@ -2,22 +2,32 @@ typedef unsigned char uint8_t; -// UART memory-mapped registers (hooked up in dpram.vhd). -// Placed at 0x70-0x72: unimplemented in the real PIC16F84A so no -// conflict with the SFR definitions in pic16f84a.h. -// 0x70 UART_TX write: transmit a byte -// 0x71 UART_RX read: receive a byte (pops the RX FIFO) -// 0x72 UART_STATUS read: bit0=tx_busy, bit1=rx_empty, bit2=rx_full __sfr __at(0x70) UART_TX; __sfr __at(0x71) UART_RX; __sfr __at(0x72) UART_STATUS; +static volatile uint8_t _d0, _d1, _d2; +static uint8_t counter; + +static void delay(void) { + _d0 = 0; + do { + _d1 = 0; + do { + _d2 = 0; + do { _d2++; } while (_d2 != 0); + } while (++_d1 != 30); + _d0++; + } while (_d0 != 116); +} + static void uart_send(uint8_t byte) { - while (UART_STATUS & 0x01); // wait until tx_busy = 0 + while (UART_STATUS & 0x01); UART_TX = byte; } -static void uart_puts(const char *s) { +// Keep this ONLY for literal strings (ROM) +static void uart_puts_rom(const char *s) { while (*s) { uart_send((uint8_t)*s); s++; @@ -25,12 +35,33 @@ static void uart_puts(const char *s) { } void main(void) { - uart_puts("Hello from PIC!\r\n"); + counter = 0; + uart_puts_rom("Hello\r\n"); - // Echo loop: read every incoming byte and send it back while (1) { - if (!(UART_STATUS & 0x02)) { // rx_empty = 0 → data available - uart_send(UART_RX); + uint8_t v = counter; + uint8_t started = 0; + + uart_send('C'); + uart_send(':'); + + // Hundreds + if (v >= 200) { uart_send('2'); v -= 200; started = 1; } + else if (v >= 100) { uart_send('1'); v -= 100; started = 1; } + + // Tens + { + uint8_t tens = '0'; + while (v >= 10) { v -= 10; tens++; } + if (started || tens != '0') { uart_send(tens); } } + + // Units (always) + uart_send(v + '0'); + + uart_puts_rom("\r\n"); + + counter++; + delay(); } } diff --git a/test_uart.hex b/test_uart.hex index 7ce88d8..70d8c2f 100644 --- a/test_uart.hex +++ b/test_uart.hex @@ -1,39 +1,50 @@ :020000040000FA -:100000000000022818309A0001309B008030000068 -:1000100000009E2000000000831200009D001B08CD -:100020009C001A309E0001309F00831200001C08C3 +:10000000000002286F309A0001309B008030000011 +:100010000000122100000000831200009D001B0858 +:100020009C0071309E0001309F00831200001C086C :10003000A0001D08A100FF309C07031C9D032108A0 :10004000200403199A2804301E07A000A101A10D65 :100050001F08A10720089A0021089B00803000009B -:1000600000009E200000000083120000A3001B0877 +:10006000000012210000000083120000A3001B0802 :10007000A2001E089A001F089B00803000000000AC -:100080009E200000000083120000A500A1001B08B4 +:1000800012210000000083120000A500A1001B083F :10009000A000A40002301E07A000A101A10D1F08AE :1000A000A10720089A0021089B0080300000000072 -:1000B0009E200000000083120000A100A7001B0882 +:1000B00012210000000083120000A100A7001B080D :1000C000A600A000831200002208A6002308A700B3 :1000D000FF30A207031CA303270826040319932853 -:1000E00024089A0025089B00803000000000BF20F3 +:1000E00024089A0025089B0080300000000033217E :1000F0000000000083120000A600200883120313F2 :1001000084008313831200002118831726088312AA :100110000313800083120000A40A0319A50AA00A91 :100120000319A10A62280630831200009E070318F3 -:100130009F0A152800000000D2280800003A031981 -:10014000A628803A0319B0289B0100341A088400BD -:1001500083131B18831700089B00840A00080800FB -:1001600000000000CD2099009A0F9B039B0A00001D -:100170000000CD20980019089B0018080800003ADC -:100180000319C628803A0319CD2800341A088400C0 -:1001900083131B188317000808001B088A001A081D -:1001A000820008000030AF00FD30AE008030B000AB -:1001B0002E089A002F089B003008AC001B08AB00EB -:1001C0001A08AA002A089A002B089B002C08BF20B6 -:1001D000AD002D080319F4282D080F21AA0A0319D0 -:1001E000AB0A0319AC0AE22883127208AE00AE18FB -:1001F000F42871080F21F4280800483465346C3461 -:100200006C346F342034663472346F346D3420347F -:1002100050344934433421340D340A340034A800B6 -:1002200083127208A900291810292808F000080074 -:1002300001340034203401343134003401340034CA -:02024000003488 +:100130009F0A1528000000009E280800B501013024 +:10014000AF006730AE008030B0002E089A002F0854 +:100150009B00300846213508AE00AF0143305E21D8 +:100160003A305E21C8302E02031CC02832305E2196 +:100170002E08B00038303007AE000130AF00CD2877 +:1001800064302E02031CCD2831305E212E08B000D1 +:100190009C303007AE000130AF003030B0000A3084 +:1001A0002E02031CDA282E08B100F6303107AE000B +:1001B000B00ACF283008B1002F08031DE32830080B +:1001C000303A0319E52831085E212E08AF0030309F +:1001D0002F07AE005E210130AF007730AE008030D7 +:1001E000B0002E089A002F089B0030084621B50A5F +:1001F000B201B301B4013408A800280AB4003408DD +:10020000031DFB28330AA800B30028081E3A031D6B +:10021000FA283208A800280AB200743A031DF92807 +:10022000AB280800003A03191A29803A0319242937 +:100230009B0100341A08840083131B1883170008DD +:100240009B00840A0008080000000000412199007A +:100250009A0F9B039B0A0000000041219800190897 +:100260009B0018080800003A03193A29803A03193C +:10027000412900341A08840083131B1883170008CF +:1002800008001B088A001A0882000800AC001B083E +:10029000AB001A08AA002A089A002B089B002C0819 +:1002A0003321AD002D0803195D292D085E21AA0A0E +:1002B0000319AB0A0319AC0A4B290800A8008312E2 +:1002C0007208A90029185F292808F000080048349E +:1002D00065346C346C346F340D340A3400340134BA +:1002E00000347A34013436340034013400340D34AF +:0602F0000A340034003462 :00000001FF -- cgit v1.3