From 6b81cccb3a6c5b01ea0ceb5dd18b0e71dc71b147 Mon Sep 17 00:00:00 2001 From: Roberto Hexsel <roberto@inf.ufpr.br> Date: Wed, 29 Mar 2017 19:29:44 -0300 Subject: [PATCH] added test to RGB lets to mac_7seg.s, assorted small fixes --- cMIPS/bin/assemble.sh | 6 +- cMIPS/include/cMIPS.h | 2 +- cMIPS/include/cMIPSio.c | 13 ++-- cMIPS/include/handlers.s | 41 ++++++------ cMIPS/include/syn_handlers.s | 66 +++++++++---------- cMIPS/tests/mac_7seg.s | 123 ++++++++++++++++++++++++++++++----- cMIPS/tests/mac_chrono.c | 18 +++-- cMIPS/vhdl/io.vhd | 28 +++++--- cMIPS/vhdl/tb_cMIPS.vhd | 24 +++---- 9 files changed, 211 insertions(+), 110 deletions(-) diff --git a/cMIPS/bin/assemble.sh b/cMIPS/bin/assemble.sh index 39b832b..7ecfc3c 100755 --- a/cMIPS/bin/assemble.sh +++ b/cMIPS/bin/assemble.sh @@ -105,10 +105,12 @@ pkg_vhd="${srcVHDL}"/packageMemory.vhd if [ $miffile = true ]; then S="-D FOR_SYNTHESIS" ; - touch $pkg_vhd -r ${srcVHDL}/packageMemory_fpga.vhd + ln -sf ${srcVHDL}/packageMemory_fpga.vhd $pkg_vhd + touch $pkg_vhd else S="-U FOR_SYNTHESIS" ; - touch $pkg_vhd -r ${srcVHDL}/packageMemory_simu.vhd + ln -sf ${srcVHDL}/packageMemory_simu.vhd $pkg_vhd + touch $pkg_vhd fi if [ $pkg_vhd -nt $c_ld -o $pkg_vhd -nt $c_s ] ; then diff --git a/cMIPS/include/cMIPS.h b/cMIPS/include/cMIPS.h index 2acad22..f69e128 100644 --- a/cMIPS/include/cMIPS.h +++ b/cMIPS/include/cMIPS.h @@ -69,7 +69,7 @@ extern void LCDputc(char); extern void LCDprint(unsigned int); // 7-segment display and keyboard (Macnica board) -extern void DSP7SEGput(int, int, int, int); +extern void DSP7SEGput(int, int, int, int, int); extern int KBDget(void); extern int SWget(void); diff --git a/cMIPS/include/cMIPSio.c b/cMIPS/include/cMIPSio.c index 5e04c49..f83265d 100644 --- a/cMIPS/include/cMIPSio.c +++ b/cMIPS/include/cMIPSio.c @@ -376,18 +376,17 @@ void LCDprint(unsigned int n) { k = (n<<28)>>28; LCDput( conv(k) ); } - - //----------------------------------------------------------------------- //======================================================================= // 7 segment display -//======================================================================= +// rgb values are in [0,7] // MSdigit bits bit7..4, lsDigit bit3..0, MSD dot bit9, lsD dot bit8 -void DSP7SEGput(int MSD, int MSdot, int lsd, int lsdot) { +//======================================================================= +void DSP7SEGput(int MSD, int MSdot, int lsd, int lsdot, int rgb) { int *IO = (int *)IO_DSP7SEG_ADDR; - int w, dot1, dot0, dig1, dig0; + int leds, dot1, dot0, dig1, dig0; dot1 = (MSdot != 0 ? 1 << 9 : 0); dot0 = (lsdot != 0 ? 1 << 8 : 0); @@ -395,7 +394,9 @@ void DSP7SEGput(int MSD, int MSdot, int lsd, int lsdot) { dig1 = (MSD & 0xf) << 4; dig0 = (lsd & 0xf); - *IO = dot1 | dot0 | dig1 | dig0; + leds = (rgb & 0x07) <<10; + + *IO = leds | dot1 | dot0 | dig1 | dig0; } //----------------------------------------------------------------------- diff --git a/cMIPS/include/handlers.s b/cMIPS/include/handlers.s index 42dc8d7..30cb85a 100644 --- a/cMIPS/include/handlers.s +++ b/cMIPS/include/handlers.s @@ -492,22 +492,20 @@ cmips_delay: #================================================================ # delays processing by $a0 times 1 microsecond - # loop takes 4 cycles = 80ns @ 50MHz - # 1.000ns / 80 = 12.5 - # multiply by 2 (sll), add 1, multiply by 12, divide by 2 (sra) + # loop takes 5 cycles = 100ns @ 50MHz + # 1.000ns / 100 = 10 .text .set noreorder .ent delay_us delay_us: - sll $a0, $a0, 1 - addiu $a0, $a0, 1 - li $v0, 12 + li $v0, 10 mult $v0, $a0 nop mflo $a0 sra $a0, $a0, 1 _d_us: addiu $a0, $a0, -1 nop + nop bne $a0, $zero, _d_us nop jr $ra @@ -515,27 +513,28 @@ _d_us: addiu $a0, $a0, -1 .end delay_us #---------------------------------------------------------------- - #================================================================ - # delays processing by $a0 times 1 msecond - # loop takes 4 cycles = 80ns @ 50MHz - # 1.000.000ns / 80 = 12500 - .text - .set noreorder - .ent delay_ms -delay_ms: - li $v0, 12500 - mult $v0, $a0 - nop - mflo $a0 -_d_ms: addiu $a0, $a0, -1 + + #================================================================ + # delays processing by $a0 times 1 mili second + # loop takes 5 cycles = 100ns @ 50MHz + # 1.000.000ns / 100 = 10.000 + .text + .set noreorder + .ent delay_ms +delay_ms: + li $v0, 10000 + mul $a0, $v0, $a0 + nop +_d_ms: addiu $a0, $a0, -1 nop + nop bne $a0, $zero, _d_ms nop jr $ra nop - .end delay_ms + .end delay_ms #---------------------------------------------------------------- - + #================================================================ # print a message from within "the kernel" diff --git a/cMIPS/include/syn_handlers.s b/cMIPS/include/syn_handlers.s index 6f02f37..081f70f 100644 --- a/cMIPS/include/syn_handlers.s +++ b/cMIPS/include/syn_handlers.s @@ -493,51 +493,49 @@ cmips_delay: .end cmips_delay #---------------------------------------------------------------- - #================================================================ - # delays processing by $a0 times 1 microsecond - # loop takes 4 cycles = 80ns @ 50MHz - # 1.000ns / 80 = 12.5 - # multiply by 2 (sll), add 1, multiply by 12, divide by 2 (sra) - .text - .set noreorder - .ent delay_us + #================================================================ + # delays processing by $a0 times 1 microsecond + # loop takes 5 cycles = 100ns @ 50MHz + # 1.000ns / 100 = 10 + .text + .set noreorder + .ent delay_us delay_us: - sll $a0, $a0, 1 - addiu $a0, $a0, 1 - li $v0, 12 - mult $v0, $a0 - nop - mflo $a0 - sra $a0, $a0, 1 -_d_us: addiu $a0, $a0, -1 + li $v0, 10 + mult $v0, $a0 + nop + mflo $a0 + sra $a0, $a0, 1 +_d_us: addiu $a0, $a0, -1 + nop nop bne $a0, $zero, _d_us nop jr $ra nop - .end delay_us - #---------------------------------------------------------------- - - #================================================================ - # delays processing by $a0 times 1 msecond - # loop takes 4 cycles = 80ns @ 50MHz - # 1.000.000ns / 80 = 12500 - .text - .set noreorder - .ent delay_ms -delay_ms: - li $v0, 12500 - mult $v0, $a0 - nop - mflo $a0 -_d_ms: addiu $a0, $a0, -1 + .end delay_us + #---------------------------------------------------------------- + + #================================================================ + # delays processing by $a0 times 1 milisecond + # loop takes 5 cycles = 100ns @ 50MHz + # 1.000.000ns / 100 = 10.000 + .text + .set noreorder + .ent delay_ms +delay_ms: + li $v0, 10000 + mul $a0, $v0, $a0 nop +_d_ms: addiu $a0, $a0, -1 + nop + nop bne $a0, $zero, _d_ms nop jr $ra nop - .end delay_ms - #---------------------------------------------------------------- + .end delay_ms + #---------------------------------------------------------------- #================================================================ diff --git a/cMIPS/tests/mac_7seg.s b/cMIPS/tests/mac_7seg.s index 3ecee8f..090e863 100644 --- a/cMIPS/tests/mac_7seg.s +++ b/cMIPS/tests/mac_7seg.s @@ -1,3 +1,6 @@ + ## + ## test the 7-segment LED displays, and the RGB-led + ## .include "cMIPS.s" .text .align 2 @@ -8,9 +11,6 @@ .set MMU_WIRED, 2 ### do not change mapping for ROM-0, I/O - .set waitFor, 50000000/4 # wait for 1 second @ 50 MHz - # .set waitFor, 5 # this is for simulation only - .org x_INST_BASE_ADDR,0 _start: nop @@ -26,7 +26,7 @@ _start: nop .org x_EXCEPTION_0000,0 _excp_0000: la $k0, HW_dsp7seg_addr # 7 segment display - li $k1, 0x0399 # display .9.9 + li $k1, 0x1399 # display .9.9, led red sw $k1, 0($k0) # write to 7 segment display h0000: j h0000 # wait forever nop @@ -34,7 +34,7 @@ h0000: j h0000 # wait forever .org x_EXCEPTION_0100,0 _excp_0100: la $k0, HW_dsp7seg_addr # 7 segment display - li $k1, 0x0388 # display .8.8 + li $k1, 0x1388 # display .8.8, led red sw $k1, 0($k0) # write to 7 segment display h0100: j h0100 # wait forever nop @@ -42,7 +42,7 @@ h0100: j h0100 # wait forever .org x_EXCEPTION_0180,0 _excp_0180: la $k0, HW_dsp7seg_addr # 7 segment display - li $k1, 0x0377 # display .7.7 + li $k1, 0x0777 # display .7.7, led blue sw $k1, 0($k0) # write to 7 segment display h0180: j h0180 # wait forever nop @@ -50,7 +50,7 @@ h0180: j h0180 # wait forever .org x_EXCEPTION_0200,0 _excp_0200: la $k0, HW_dsp7seg_addr # 7 segment display - li $k1, 0x0366 # display .6.6 + li $k1, 0x0766 # display .6.6, led blue sw $k1, 0($k0) # write to 7 segment display h0200: j h0200 # wait forever nop @@ -58,7 +58,7 @@ h0200: j h0200 # wait forever .org x_EXCEPTION_BFC0,0 _excp_BFC0: la $k0, HW_dsp7seg_addr # 7 segment display - li $k1, 0x0355 # display .5.5 + li $k1, 0x0b55 # display .5.5, led green sw $k1, 0($k0) # write to 7 segment display hBFC0: j hBFC0 # wait forever nop @@ -68,23 +68,110 @@ hBFC0: j hBFC0 # wait forever # main ----------------------------------------------------- # main: la $25, HW_dsp7seg_addr # 7 segment display - la $5, waitFor - li $3, 0 + + # + # light up leds RED, GREEN, BLUE + # turn {R.G,B} led on for 1 sec, turn it off for 1 sec, + # repeat for next color + # + li $9, 0x1000 # light up led RED + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 + + li $9, 0x0000 # turn off leds + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 + + li $9, 0x0800 # light up led GREEN + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 + + li $9, 0x0000 # turn off leds + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 + + li $9, 0x0400 # light up led BLUE + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 + + li $9, 0x0000 # turn off leds + sw $9, 0($25) # write to 7 segment display + jal delay_ms + la $a0, 1000 -new: sw $3, 0($25) # write to 7 segment display - nop -wait: addiu $5, $5, -1 - bne $5, $zero, wait - nop - la $5, waitFor # wait for 1 second @ 50 MHz - addiu $3, $3, 1 # change digit - b new # repeat forever + # + # write 0..0xff to the 7-segment displays + # when count reaches 0xff+1, turn on least significant dot + # when count reaches 0xfff+1, turn on most significant dot + # meanwhile, light up one of the 9 colors for 3/4 of a second + # + li $3,0 + +new: addiu $3, $3, 1 # change digit + andi $3, $3, 0x03ff # keep it into 2 digits plus dots + andi $4, $3, 0x0007 # keep only 3 bits for RGB + sll $4, $4, 10 # light up the leds + or $3, $3, $4 + sw $3, 0($25) # write to 7 segment display + + jal delay_ms + li $a0, 750 # wait 3/4 second + + andi $3, $3, 0x003ff # turn off leds + sw $3, 0($25) # write to 7 segment display + + jal delay_ms + li $a0, 250 # wait 1/4 second + + b new # and repeat forever nop + end1: nop nop + nop nop wait nop nop .end _start + + + #================================================================ + # delays processing by $a0 times 1 mili second + # loop takes 5 cycles = 100ns @ 50MHz + # 1.000.000ns / 100 = 10.000 + .text + .set noreorder + .ent delay_ms +delay_ms: + li $v0, 10000 + mul $a0, $v0, $a0 + nop +_d_ms: addiu $a0, $a0, -1 + nop + nop + bne $a0, $zero, _d_ms + nop + jr $ra + nop + .end delay_ms + #---------------------------------------------------------------- + + + + # not used, just to shut up the linker. + .bss +nil1: .space 4 + .sbss + .data +nil3: .word 0 + .sdata +nil4: .word 0 + + diff --git a/cMIPS/tests/mac_chrono.c b/cMIPS/tests/mac_chrono.c index d9605c3..84c27be 100644 --- a/cMIPS/tests/mac_chrono.c +++ b/cMIPS/tests/mac_chrono.c @@ -2,7 +2,7 @@ // chronometer on the LCD display // // external counter interrupts 4 times per second -// displays shows a tumbling star plus counter that increments every second +// displays shows a tumbling wheel; (hex) counter increments every second // #include "cMIPS.h" @@ -40,7 +40,7 @@ int main(void) { LCDput('d'); LCDput('!'); #else - LCDprint( print_sp() ); + LCDprint( print_sp() ); // for debugging only #endif LCDbotLine(); @@ -50,7 +50,7 @@ int main(void) { old_val = _counter_val; enableInterr(); - startCounter(QUARTER,TRUE); // counter will interrupt after N cycles + startCounter(QUARTER,TRUE); // counter will interrupt after 1/4 second sec = min = hour = 0; @@ -58,8 +58,8 @@ int main(void) { while (TRUE) { - while (old_val == _counter_val) {// wait for interrupt - delay_us(i); + while (old_val == _counter_val) { // busy wait for interrupt + delay_us(i); // that's really stupid but we have nothing else to do } old_val = _counter_val; @@ -72,9 +72,13 @@ int main(void) { case 2: j = 0x0c; break; default: - j = 0xa; i = -1; sec += 1 ; break; + j = 0xa; + i = -1; + sec += 1; + break; }; - i += 1; + i += 1; + DSP7SEGput(0, 0, 0, 0, (i<<2)); // blink red led LCDgotoxy(1, 2); LCDput(j); diff --git a/cMIPS/vhdl/io.vhd b/cMIPS/vhdl/io.vhd index 4d13cd8..ece5e4d 100644 --- a/cMIPS/vhdl/io.vhd +++ b/cMIPS/vhdl/io.vhd @@ -484,6 +484,9 @@ end behavioral; --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- peripheral: to_7seg +-- input format: +-- b12 b11 b10 b09 b08 b07..b04 b03..b02 +-- red gre blu MSdot msdot MSdigit msdigit --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ library IEEE; use IEEE.std_logic_1164.all; @@ -498,10 +501,14 @@ entity to_7seg is wr : in std_logic; data : in std_logic_vector; display0 : out reg8; - display1 : out reg8); - constant NUM_BITS : integer := 10; -- 2 decimal points, 2 hex digits + display1 : out reg8; + red : out std_logic; + green : out std_logic; + blue : out std_logic); + -- 2 decimal points, 2 hex digits, 3 leds + constant NUM_BITS : integer := 13; subtype c_width is std_logic_vector(NUM_BITS - 1 downto 0); - constant START_COUNT : c_width := (others => '0'); + constant INIT_VALUE : c_width := (others => '0'); end to_7seg; architecture behavioral of to_7seg is @@ -519,19 +526,22 @@ architecture behavioral of to_7seg is disp_7seg_o : out std_logic_vector(7 downto 0)); end component display_7seg; - signal value : std_logic_vector(NUM_BITS-1 downto 0); + signal value : std_logic_vector(NUM_BITS-1 downto 0); signal middle : std_logic; begin - U_HOLD_data: registerN generic map (NUM_BITS, START_COUNT) + U_HOLD_data: registerN generic map (NUM_BITS, INIT_VALUE) port map (clk, rst, sel, data(NUM_BITS-1 downto 0), value); + red <= value(12); + green <= value(11); + blue <= value(10); + U_DSP1: display_7seg port map (value(7 downto 4), value(9), display1); U_DSP0: display_7seg port map (value(3 downto 0), value(8), display0); - U_sim: process(sel,rst,clk) begin middle <= not(sel) and not(clk); -- to remove spurious reports @@ -741,7 +751,7 @@ entity LCD_display is LCD_BLON : out std_logic); constant NUM_BITS : integer := 8; subtype c_width is std_logic_vector(NUM_BITS - 1 downto 0); - constant START_VALUE : c_width := (others => '0'); + constant INIT_VALUE : c_width := (others => '0'); end LCD_display; architecture behavioral of LCD_display is @@ -793,10 +803,10 @@ begin sel_rs <= addr when sel = '0' else RS; U_INPUT_RS: FFDsimple port map (clk, rst, sel_rs, RS); - U_INPUT: registerN generic map (NUM_BITS, START_VALUE) + U_INPUT: registerN generic map (NUM_BITS, INIT_VALUE) port map (clk, rst, sel, data_inp(NUM_BITS-1 downto 0), inp_data); - U_OUTPUT: registerN generic map (NUM_BITS, START_VALUE) + U_OUTPUT: registerN generic map (NUM_BITS, INIT_VALUE) port map (clk, rst, lcd_read, out_data, data_out(NUM_BITS-1 downto 0)); data_out(31 downto NUM_BITS) <= (others => 'X'); diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd index 80d615b..5260039 100644 --- a/cMIPS/vhdl/tb_cMIPS.vhd +++ b/cMIPS/vhdl/tb_cMIPS.vhd @@ -58,7 +58,10 @@ architecture TB of tb_cMIPS is wr : in std_logic; data : in std_logic_vector; display0 : out std_logic_vector; - display1 : out std_logic_vector); + display1 : out std_logic_vector; + red : out std_logic; + green : out std_logic; + blue : out std_logic); end component to_7seg; component read_keys is @@ -450,9 +453,9 @@ architecture TB of tb_cMIPS is -- Macnica development board's peripherals signal disp0,disp1 : reg8; -- 7 segment displays - signal keys : reg12; -- 12key telephone keyboard - signal switches : reg4; -- 4 switches - signal led_r, led_g, led_b : std_logic; -- RGB leds + signal keys : reg12; -- 12 key telephone keyboard + signal sw : reg4; -- 4 slide switches + signal led_r, led_g, led_b : std_logic; -- RGB leds (on board signals) signal LCD_DATA : std_logic_vector(7 downto 0); -- LCD data bus signal LCD_RS, LCD_RW, LCD_EN, LCD_BLON : std_logic; -- LCD control signal uart_txd, uart_rxd, uart_rts, uart_cts, uart_irq : std_logic; @@ -606,18 +609,15 @@ begin -- TB U_to_7seg: to_7seg - port map (rst,clk,io_7seg_sel, wr, cpu_data, disp0, disp1); + port map (rst,clk,io_7seg_sel, wr, cpu_data, disp0, disp1, + led_r, led_g, led_b); keys <= b"000000000000", b"000000000100" after 1 us, b"000000000000" after 2 us, b"001000000000" after 3 us, b"000000000000" after 4 us, b"000001000000" after 5 us, b"000000000000" after 6 us; - switches <= b"0000"; + sw <= b"0000"; U_read_keys: read_keys generic map (6) -- debouncing interval, in clock cycles - port map (rst,clk, io_keys_sel, keybd_d_out, keys, switches); - - led_r <= keybd_d_out(0); - led_g <= keybd_d_out(1); - led_b <= keybd_d_out(2); + port map (rst,clk, io_keys_sel, keybd_d_out, keys, sw); U_LCD_display: LCD_display port map (rst, clk, io_lcd_sel, io_lcd_wait, @@ -782,7 +782,7 @@ begin dev_select <= b"0001" when (cpu_d_aVal = '0' and in_range) else b"0000"; - assert true -- cpu_d_aVal = '1' + assert TRUE -- cpu_d_aVal = '1' report "e " & SLV32HEX(addr) & " addr " & SLV2str(addr(15 downto 0)) & LF & " LO_AD " & integer'image(LO_ADDR) & -- GitLab