hiram

Picoblaze使用范例(一)LCD显示,基于spartan3e start kit

0
阅读(3178)
Technorati 标签:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Hiram Lee yangli0534@gmail.com
// 
// Create Date:    18:33:26 05/06/2012 
// Design Name:     lcd test via Picoblaze on Spartan 3e start kit
// Module Name:     lcd 
// Project Name:    lcd test 
// Target Devices:  x3cs500e fp320
// Tool versions:   ise 10.1.03
// Description:     Print "PicoBlaze " on the LCD 
// Reference Design: Xilinx PicoBlaze controlling the two channel programmable 
//                  amplifier type LTC6912-1 and two channel A/D converter type LTC1407A-1 from 
//                  Linear Technology.
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module lcd 
   (
      input wire clk, reset,
      output wire lcd_rs, lcd_rw, lcd_e,
      output wire strataflash_oe, strataflash_ce, strataflash_we, platformflash_oe,
     inout wire [7:4] lcd_d
    );

    wire [9:0] address;
     wire [17:0] instruction;
     wire [7:0] in_port, out_port, port_id;
     wire write_strobe, read_strobe;
    
     
     
    //kcpsm3 and instruction memory
     kcpsm3 unit_proc(
     .address(address),
     .instruction(instruction),
     .port_id(port_id),
     .write_strobe(write_strobe),
     .out_port(out_port),
     .read_strobe(read_strobe),
     .in_port(in_port),
     .interrupt(1'b0),
     .interrupt_ack(),
     .reset(reset),
     .clk(clk)) ;

  program unit_rom(.address(address), .instruction(instruction), .clk(clk));
              
  //----------------------------------------------------------------------------------------------------------------------------------
  // Input interface  
  //----------------------------------------------------------------------------------------------------------------------------------

   reg in_port_data;
   always @(posedge clk)
       if(read_strobe==1'b1 && port_id[1] == 1'b1)
          
              in_port_data<=lcd_d & 8'hf0;
            
       else
            in_port_data <= 8'hzz;
    assign in_port = in_port_data;    
   //    ----------------------------------------------------------------------------------------------------------------------------------
   // Output interface  
   //---------------------------------------------------------------------------------------------------------------------------------

  //disable the signal that share the same port
  assign strataflash_oe = 1'b1, 
         strataflash_ce = 1'b1, 
            strataflash_we = 1'b1,
            platformflash_oe = 1'b0;
   // read and write control
   reg lcd_rw_control, lcd_drive,  lcd_rs_reg, lcd_e_reg;
    reg [7:4] lcd_out_data;
    always @(posedge clk)
       if(write_strobe==1'b1 && port_id[6] == 1'b1)
           begin
               lcd_out_data <= out_port[7:4];
                lcd_drive <= out_port[3];
                lcd_rs_reg <= out_port[2];
                lcd_rw_control <= out_port[1];
                lcd_e_reg  <= out_port[0];
            end
    assign lcd_rs = lcd_rs_reg,
           lcd_e  = lcd_e_reg;
  //----------------------------------------------------------------------------------------------------------------------------------
  // LCD interface  
  //----------------------------------------------------------------------------------------------------------------------------------
  
 
  assign lcd_rw = lcd_rw_control & lcd_drive;
  assign lcd_d =  (lcd_rw_control==1'b0 && lcd_drive==1'b1) ? lcd_out_data :4'bZZZZ;
endmodule

其中PicoBlaze的汇编程序如下:

 

                    ;fuction: print 'PicoBlaze' on the screen
                          ;LCD interface ports
                    ;
                    ;The master enable signal is not used by the LCD display itself
                    ;but may be required to confirm that LCD communication is active.
                    ;This is required on the Spartan-3E Starter Kit if the StrataFLASH
                    ;is used because it shares the same data pins and conflicts must be avoided.
                    ;
                    CONSTANT LCD_output_port, 40        ;LCD character module output data and control
                    CONSTANT LCD_E, 01                  ;   active High Enable        E - bit0
                    CONSTANT LCD_RW, 02                 ;   Read=1 Write=0           RW - bit1
                    CONSTANT LCD_RS, 04                 ;   Instruction=0 Data=1     RS - bit2
                    CONSTANT LCD_drive, 08              ;   Master enable (active High) - bit3
                    CONSTANT LCD_DB4, 10                ;   4-bit              Data DB4 - bit4
                    CONSTANT LCD_DB5, 20                ;   interface          Data DB5 - bit5
                    CONSTANT LCD_DB6, 40                ;                      Data DB6 - bit6
                    CONSTANT LCD_DB7, 80                ;                      Data DB7 - bit7
                    ;
                    ;
                    CONSTANT LCD_input_port, 02         ;LCD character module input data
                    CONSTANT LCD_read_spare0, 01        ;    Spare bits               - bit0
                    CONSTANT LCD_read_spare1, 02        ;    are zero                 - bit1
                    CONSTANT LCD_read_spare2, 04        ;                             - bit2
                    CONSTANT LCD_read_spare3, 08        ;                             - bit3
                    CONSTANT LCD_read_DB4, 10           ;    4-bit           Data DB4 - bit4
                    CONSTANT LCD_read_DB5, 20           ;    interface       Data DB5 - bit5
                    CONSTANT LCD_read_DB6, 40           ;                    Data DB6 - bit6
                    CONSTANT LCD_read_DB7, 80           ;                    Data DB7 - bit7
                    ;
                    ;

                    ;Constant to define a software delay of 1us. This must be adjusted to reflect the
                    ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
                    ;calculation highly predictable. The '6' in the following equation even allows for
                    ;'CALL delay_1us' instruction in the initiating code.
                    ;
                    ; delay_1us_constant =  (clock_rate - 6)/4       Where 'clock_rate' is in MHz
                    ;
                    ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11  (0B Hex).
                    ;For clock rates below 10MHz the value of 1 must be used and the operation will
                    ;become lower than intended.
                    ;
                    CONSTANT delay_1us_constant, 0B
                    ;
                    ;
                    ;
                    ;ASCII table
                    ;
                    CONSTANT character_a, 61
                    CONSTANT character_b, 62
                    CONSTANT character_c, 63
                    CONSTANT character_d, 64
                    CONSTANT character_e, 65
                    CONSTANT character_f, 66
                    CONSTANT character_g, 67
                    CONSTANT character_h, 68
                    CONSTANT character_i, 69
                    CONSTANT character_j, 6A
                    CONSTANT character_k, 6B
                    CONSTANT character_l, 6C
                    CONSTANT character_m, 6D
                    CONSTANT character_n, 6E
                    CONSTANT character_o, 6F
                    CONSTANT character_p, 70
                    CONSTANT character_q, 71
                    CONSTANT character_r, 72
                    CONSTANT character_s, 73
                    CONSTANT character_t, 74
                    CONSTANT character_u, 75
                    CONSTANT character_v, 76
                    CONSTANT character_w, 77
                    CONSTANT character_x, 78
                    CONSTANT character_y, 79
                    CONSTANT character_z, 7A
                    CONSTANT character_A, 41
                    CONSTANT character_B, 42
                    CONSTANT character_C, 43
                    CONSTANT character_D, 44
                    CONSTANT character_E, 45
                    CONSTANT character_F, 46
                    CONSTANT character_G, 47
                    CONSTANT character_H, 48
                    CONSTANT character_I, 49
                    CONSTANT character_J, 4A
                    CONSTANT character_K, 4B
                    CONSTANT character_L, 4C
                    CONSTANT character_M, 4D
                    CONSTANT character_N, 4E
                    CONSTANT character_O, 4F
                    CONSTANT character_P, 50
                    CONSTANT character_Q, 51
                    CONSTANT character_R, 52
                    CONSTANT character_S, 53
                    CONSTANT character_T, 54
                    CONSTANT character_U, 55
                    CONSTANT character_V, 56
                    CONSTANT character_W, 57
                    CONSTANT character_X, 58
                    CONSTANT character_Y, 59
                    CONSTANT character_Z, 5A
                    CONSTANT character_0, 30
                    CONSTANT character_1, 31
                    CONSTANT character_2, 32
                    CONSTANT character_3, 33
                    CONSTANT character_4, 34
                    CONSTANT character_5, 35
                    CONSTANT character_6, 36
                    CONSTANT character_7, 37
                    CONSTANT character_8, 38
                    CONSTANT character_9, 39
                    CONSTANT character_colon, 3A
                    CONSTANT character_stop, 2E
                    CONSTANT character_semi_colon, 3B
                    CONSTANT character_minus, 2D
                    CONSTANT character_divide, 2F       ;'/'
                    CONSTANT character_plus, 2B
                    CONSTANT character_comma, 2C
                    CONSTANT character_less_than, 3C
                    CONSTANT character_greater_than, 3E
                    CONSTANT character_equals, 3D
                    CONSTANT character_space, 20
                    CONSTANT character_CR, 0D           ;carriage return
                    CONSTANT character_question, 3F     ;'?'
                    CONSTANT character_dollar, 24
                    CONSTANT character_exclaim, 21      ;'!'
                    CONSTANT character_BS, 08           ;Back Space command character
                    ;

                    ;routine
                    ;initializaion
                    ;print
                          
            cold_start: call LCD_reset                       ;initialise LCD display
                       ;Write welcome message to LCD display
                    ;
                    LOAD s5, 10                         ;Line 1 position 0
                    CALL LCD_cursor
                    CALL disp_PicoBlaze                 ;Display 'PicoBlaze Inside'
                    stop:load s0,s0                          ;
                         jump stop
                       ;**************************************************************************************
                    ;LCD text messages
                    ;**************************************************************************************
                    ;
                    ;
                    ;Display 'PicoBlaze' on LCD at current cursor position
                    ;
                    ;
    disp_PicoBlaze: LOAD s5, character_P
                    CALL LCD_write_data
                    LOAD s5, character_i
                    CALL LCD_write_data
                    LOAD s5, character_c
                    CALL LCD_write_data
                    LOAD s5, character_o
                    CALL LCD_write_data
                    LOAD s5, character_B
                    CALL LCD_write_data
                    LOAD s5, character_l
                    CALL LCD_write_data
                    LOAD s5, character_a
                    CALL LCD_write_data
                    LOAD s5, character_z
                    CALL LCD_write_data
                    LOAD s5, character_e
                    CALL LCD_write_data
                    RETURN
                    ;
                          ;**************************************************************************************
                    ;Software delay routines
                    ;**************************************************************************************
                    ;
                    ;
                    ;
                    ;Delay of 1us.
                    ;
                    ;Constant value defines reflects the clock applied to KCPSM3. Every instruction
                    ;executes in 2 clock cycles making the calculation highly predictable. The '6' in
                    ;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
                    ;
                    ; delay_1us_constant =  (clock_rate - 6)/4       Where 'clock_rate' is in MHz
                    ;
                    ;Registers used s0
                    ;
         delay_1us: LOAD s0, delay_1us_constant
          wait_1us: SUB s0, 01
                    JUMP NZ, wait_1us
                    RETURN
                    ;
                    ;Delay of 40us.
                    ;
                    ;Registers used s0, s1
                    ;
        delay_40us: LOAD s1, 28                         ;40 x 1us = 40us
         wait_40us: CALL delay_1us
                    SUB s1, 01
                    JUMP NZ, wait_40us
                    RETURN
                    ;
                    ;
                    ;Delay of 1ms.
                    ;
                    ;Registers used s0, s1, s2
                    ;
         delay_1ms: LOAD s2, 19                         ;25 x 40us = 1ms
          wait_1ms: CALL delay_40us
                    SUB s2, 01
                    JUMP NZ, wait_1ms
                    RETURN
                    ;
                    ;Delay of 20ms.
                    ;
                    ;Delay of 20ms used during initialisation.
                    ;
                    ;Registers used s0, s1, s2, s3
                    ;
        delay_20ms: LOAD s3, 14                         ;20 x 1ms = 20ms
         wait_20ms: CALL delay_1ms
                    SUB s3, 01
                    JUMP NZ, wait_20ms
                    RETURN
                    ;
                    ;Delay of approximately 1 second.
                    ;
                    ;Registers used s0, s1, s2, s3, s4
                    ;
          delay_1s: LOAD s4, 32                         ;50 x 20ms = 1000ms
           wait_1s: CALL delay_20ms
                    SUB s4, 01
                    JUMP NZ, wait_1s
                    RETURN
                    ;
                    ;
                    ;
                    ;**************************************************************************************
                    ;LCD Character Module Routines
                    ;**************************************************************************************
                    ;
                    ;LCD module is a 16 character by 2 line display but all displays are very similar
                    ;The 4-wire data interface will be used (DB4 to DB7).
                    ;
                    ;The LCD modules are relatively slow and software delay loops are used to slow down
                    ;KCPSM3 adequately for the LCD to communicate. The delay routines are provided in
                    ;a different section (see above in this case).
                    ;
                    ;
                    ;Pulse LCD enable signal 'E' high for greater than 230ns (1us is used).
                    ;
                    ;Register s4 should define the current state of the LCD output port.
                    ;
                    ;Registers used s0, s4
                    ;
       LCD_pulse_E: XOR s4, LCD_E                       ;E=1
                    OUTPUT s4, LCD_output_port
                    CALL delay_1us
                    XOR s4, LCD_E                       ;E=0
                    OUTPUT s4, LCD_output_port
                    RETURN
                    ;
                    ;Write 4-bit instruction to LCD display.
                    ;
                    ;The 4-bit instruction should be provided in the upper 4-bits of register s4.
                    ;Note that this routine does not release the master enable but as it is only
                    ;used during initialisation and as part of the 8-bit instruction write it
                    ;should be acceptable.
                    ;
                    ;Registers used s4
                    ;
   LCD_write_inst4: AND s4, F8                          ;Enable=1 RS=0 Instruction, RW=0 Write, E=0
                    OUTPUT s4, LCD_output_port          ;set up RS and RW >40ns before enable pulse
                    CALL LCD_pulse_E
                    RETURN
                    ;
                    ;
                    ;Write 8-bit instruction to LCD display.
                    ;
                    ;The 8-bit instruction should be provided in register s5.
                    ;Instructions are written using the following sequence
                    ; Upper nibble
                    ; wait >1us
                    ; Lower nibble
                    ; wait >40us
                    ;
                    ;Registers used s0, s1, s4, s5
                    ;
   LCD_write_inst8: LOAD s4, s5
                    AND s4, F0                          ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
                    OR s4, LCD_drive                    ;Enable=1
                    CALL LCD_write_inst4                ;write upper nibble
                    CALL delay_1us                      ;wait >1us
                    LOAD s4, s5                         ;select lower nibble with
                    SL1 s4                              ;Enable=1
                    SL0 s4                              ;RS=0 Instruction
                    SL0 s4                              ;RW=0 Write
                    SL0 s4                              ;E=0
                    CALL LCD_write_inst4                ;write lower nibble
                    CALL delay_40us                     ;wait >40us
                    LOAD s4, F0                         ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
                    OUTPUT s4, LCD_output_port          ;Release master enable
                    RETURN
                    ;
                    ;
                    ;
                    ;Write 8-bit data to LCD display.
                    ;
                    ;The 8-bit data should be provided in register s5.
                    ;Data bytes are written using the following sequence
                    ; Upper nibble
                    ; wait >1us
                    ; Lower nibble
                    ; wait >40us
                    ;
                    ;Registers used s0, s1, s4, s5
                    ;
    LCD_write_data: LOAD s4, s5
                    AND s4, F0                          ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
                    OR s4, 0C                           ;Enable=1 RS=1 Data, RW=0 Write, E=0
                    OUTPUT s4, LCD_output_port          ;set up RS and RW >40ns before enable pulse
                    CALL LCD_pulse_E                    ;write upper nibble
                    CALL delay_1us                      ;wait >1us
                    LOAD s4, s5                         ;select lower nibble with
                    SL1 s4                              ;Enable=1
                    SL1 s4                              ;RS=1 Data
                    SL0 s4                              ;RW=0 Write
                    SL0 s4                              ;E=0
                    OUTPUT s4, LCD_output_port          ;set up RS and RW >40ns before enable pulse
                    CALL LCD_pulse_E                    ;write lower nibble
                    CALL delay_40us                     ;wait >40us
                    LOAD s4, F0                         ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
                    OUTPUT s4, LCD_output_port          ;Release master enable
                    RETURN
                    ;
                    ;
                    ;
                    ;
                    ;Read 8-bit data from LCD display.
                    ;
                    ;The 8-bit data will be read from the current LCD memory address
                    ;and will be returned in register s5.
                    ;It is advisable to set the LCD address (cursor position) before
                    ;using the data read for the first time otherwise the display may
                    ;generate invalid data on the first read.
                    ;
                    ;Data bytes are read using the following sequence
                    ; Upper nibble
                    ; wait >1us
                    ; Lower nibble
                    ; wait >40us
                    ;
                    ;Registers used s0, s1, s4, s5
                    ;
    LCD_read_data8: LOAD s4, 0E                         ;Enable=1 RS=1 Data, RW=1 Read, E=0
                    OUTPUT s4, LCD_output_port          ;set up RS and RW >40ns before enable pulse
                    XOR s4, LCD_E                       ;E=1
                    OUTPUT s4, LCD_output_port
                    CALL delay_1us                      ;wait >260ns to access data
                    INPUT s5, LCD_input_port            ;read upper nibble
                    XOR s4, LCD_E                       ;E=0
                    OUTPUT s4, LCD_output_port
                    CALL delay_1us                      ;wait >1us
                    XOR s4, LCD_E                       ;E=1
                    OUTPUT s4, LCD_output_port
                    CALL delay_1us                      ;wait >260ns to access data
                    INPUT s0, LCD_input_port            ;read lower nibble
                    XOR s4, LCD_E                       ;E=0
                    OUTPUT s4, LCD_output_port
                    AND s5, F0                          ;merge upper and lower nibbles
                    SR0 s0
                    SR0 s0
                    SR0 s0
                    SR0 s0
                    OR s5, s0
                    LOAD s4, 04                         ;Enable=0 RS=1 Data, RW=0 Write, E=0
                    OUTPUT s4, LCD_output_port          ;Stop reading 5V device and release master enable
                    CALL delay_40us                     ;wait >40us
                    RETURN
                    ;
                    ;
                    ;Reset and initialise display to communicate using 4-bit data mode
                    ;Includes routine to clear the display.
                    ;
                    ;Requires the 4-bit instructions 3,3,3,2 to be sent with suitable delays
                    ;following by the 8-bit instructions to set up the display.
                    ;
                    ;  28 = '001' Function set, '0' 4-bit mode, '1' 2-line, '0' 5x7 dot matrix, 'xx'
                    ;  06 = '000001' Entry mode, '1' increment, '0' no display shift
                    ;  0C = '00001' Display control, '1' display on, '0' cursor off, '0' cursor blink off
                    ;  01 = '00000001' Display clear
                    ;
                    ;Registers used s0, s1, s2, s3, s4
                    ;
         LCD_reset: CALL delay_20ms                     ;wait more that 15ms for display to be ready
                    LOAD s4, 30
                    CALL LCD_write_inst4                ;send '3'
                    CALL delay_20ms                     ;wait >4.1ms
                    CALL LCD_write_inst4                ;send '3'
                    CALL delay_1ms                      ;wait >100us
                    CALL LCD_write_inst4                ;send '3'
                    CALL delay_40us                     ;wait >40us
                    LOAD s4, 20
                    CALL LCD_write_inst4                ;send '2'
                    CALL delay_40us                     ;wait >40us
                    LOAD s5, 28                         ;Function set
                    CALL LCD_write_inst8
                    LOAD s5, 06                         ;Entry mode
                    CALL LCD_write_inst8
                    LOAD s5, 0C                         ;Display control
                    CALL LCD_write_inst8
         LCD_clear: LOAD s5, 01                         ;Display clear
                    CALL LCD_write_inst8
                    CALL delay_1ms                      ;wait >1.64ms for display to clear
                    CALL delay_1ms
                    RETURN
                    ;
                    ;Position the cursor ready for characters to be written.
                    ;The display is formed of 2 lines of 16 characters and each
                    ;position has a corresponding address as indicated below.
                    ;
                    ;                   Character position
                    ;           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
                    ;
                    ; Line 1 - 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
                    ; Line 2 - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
                    ;
                    ;This routine will set the cursor position using the value provided
                    ;in register s5. The upper nibble will define the line and the lower
                    ;nibble the character position on the line.
                    ; Example s5 = 2B will position the cursor on line 2 position 11
                    ;
                    ;Registers used s0, s1, s2, s3, s4
                    ;
        LCD_cursor: TEST s5, 10                         ;test for line 1
                    JUMP Z, set_line2
                    AND s5, 0F                          ;make address in range 80 to 8F for line 1
                    OR s5, 80
                    CALL LCD_write_inst8                ;instruction write to set cursor
                    RETURN
         set_line2: AND s5, 0F                          ;make address in range C0 to CF for line 2
                    OR s5, C0
                    CALL LCD_write_inst8                ;instruction write to set cursor
                    RETURN
                    ;
                    ;
 1 Thessalonians 5:16-18“Rejoice always, pray continually, give thanks in all circumstances; for this is God’s will for you in Christ Jesus