low_cost_design_authentication_for_spartan_3e.vhd

来自「基于spartan3e的串口调试和检测程序,可直接烧写,检测结果将同时通过LCD」· VHDL 代码 · 共 911 行 · 第 1/3 页

VHD
911
字号
  --
  -- The LSB of the data bus to and from the StrataFLASH device (D0) is connected to many components.
  -- This occurs because the board provides multiple ways to configure the Spartan-3E device and   
  -- consequently all these use the configuration DIN pin. Since one of these configuration options 
  -- is SPI memory, the board also implements an SPI bus to which further devices are connected.
  -- The following signals ensure that additional connections to 'D0' can not cause any conflict with 
  -- access to the StrataFLASH device.
  --
  platformflash_oe <= '0';    --Disable (reset) Platform FLASH device used in master serial configuration.
  spi_rom_cs <= '1';          --Disable SPI FLASH device used in SPI configuration.
  spi_dac_cs <= '1';          --Disable SPI based D/A converter interface.
  spi_adc_conv <= '0';        --Prevent SPI based A/D converter from generating sample data.
  spi_sck <= en_16_x_baud;    --Provide pulses to clock A/D converter. If the A/D converter has previously received a CONV pulse
                              --  it requires 34 clock pulses to return its output back to Hi-Z.
  --
  --
  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- THE 'REAL APPLICATION' 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- The following logic defines an LED sequencing process that is representative of a real design.
  -- As well as flashing the LEDs under valid authenticated conditions it can be disabled in various ways 
  -- or produce some unexpected behaviour when the design is not authorised to work.
  -- 
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Application LED outputs 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  --
  -- For design authentication purposes, some LED outputs can be turned off to prevent full operation of the design.
  -- Others are swapped over. By not turning off all outputs and performing otherwise illogical operations when a design 
  -- is unauthorised it makes the situation more confusing to an attacker.
  --

  led(0) <= led_drive(0) when (security_disable_outputs='0') else 'Z';
  led(1) <= led_drive(1);
  led(2) <= led_drive(2) when (security_disable_outputs='0') else 'Z';
  led(3) <= led_drive(3) when (security_disable_outputs='0') else led_drive(7);
  led(4) <= led_drive(4);
  led(5) <= led_drive(5) when (security_disable_outputs='0') else 'Z';
  led(6) <= led_drive(6) when (security_disable_outputs='0') else 'Z';
  led(7) <= led_drive(7) when (security_disable_outputs='0') else led_drive(2);

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Application KCPSM3 and program memory 
  ----------------------------------------------------------------------------------------------------------------------------------
  --

  application_processor: kcpsm3
    port map(      address => application_address,
               instruction => application_instruction,
                   port_id => application_port_id,
              write_strobe => application_write_strobe,
                  out_port => application_out_port,
               read_strobe => application_read_strobe,
                   in_port => application_in_port,
                 interrupt => application_interrupt,
             interrupt_ack => application_interrupt_ack,
                     reset => application_kcpsm3_reset,
                       clk => clk);
 
  application_program_rom: led_ctrl
    port map(      address => application_address,
               instruction => application_instruction,
              --proc_reset => application_kcpsm3_reset,     --Used in JTAG_loader version
                       clk => clk);

  application_kcpsm3_reset <= '0';                          --For normal processor memory

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Application processor interrupt 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  --
  -- Interrupt is used to set timing of the application PicoBlaze during PWM generation.
  -- Interrupts are generated at a rate consistent with a resolution 256 steps of a 1KHz pulse 
  -- repetition frequency waveform. Therefore an interrupt is required every 3.92us which is 
  -- equivalent to once every 196 cycles when using the 50MHz clock provided on the Starter Kit board.
  --
  -- For design authentication purposes, the interrupts can be disabled and therefore stop normal operation 
  -- of the application processor.
  --
   
  application_interrupt_control: process(clk)
  begin
    if clk'event and clk='1' then

      --Generate interrupt every 3.92us  
      if security_disable_interrupts='0' then     --only count if authorised to do so.
        if application_interrupt_count=195 then
           application_interrupt_count <= 0;
           application_interrupt_event <= '1';
         else
           application_interrupt_count <= application_interrupt_count + 1;
           application_interrupt_event <= '0';
        end if;
      end if;

      -- processor interrupt waits for an acknowledgement
      if application_interrupt_ack='1' then
         application_interrupt <= '0';
        elsif application_interrupt_event='1' then
         application_interrupt <= '1';
        else
         application_interrupt <= application_interrupt;
      end if;

    end if; 
  end process application_interrupt_control;


  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Application processor output ports 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
   
  application_output_ports: process(clk)
  begin

    if clk'event and clk='1' then
      if application_write_strobe='1' then

        -- Control LEDs at port address 80 hex 
        if application_port_id(7)='1' then
          led_drive <= application_out_port;
        end if;

        -- Generate interrupt to authentication processor at port address 40 hex 
        if application_port_id(6)='1' then
          security_interrupt <= application_out_port(0);
        end if;

        -- Reset link FIFO at port 20 address hex 
        if application_port_id(5)='1' then
          reset_link_fifo <= application_out_port(0);
        end if;

      end if;

    end if; 

  end process application_output_ports;

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Application processor input ports 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  --
  -- The inputs connect via a pipelined multiplexer
  --

  application_input_ports: process(clk)
  begin
    if clk'event and clk='1' then

      case application_port_id(1 downto 0) is
        
        -- read back drive value of LEDs 00 hex
        when "00" =>    application_in_port <= led_drive;

        -- read status of FIFO buffer link from security processor 01 hex
        when "01" =>    application_in_port <= "00000" & link_fifo_buffer_full & link_fifo_half_full & link_fifo_data_present;

        -- read FIFO buffer link from security processor 02 hex
        when "10" =>    application_in_port <= link_fifo_data;


        -- Don't care used for all other addresses to ensure minimum logic implementation
        when others =>    application_in_port <= "XXXXXXXX";  

      end case;

      -- Form read strobe for the FIFO buffer at address 02 hex.
      -- The fact that the read strobe will occur after the actual data is read by 
      -- the KCPSM3 is acceptable because it is really means 'I have read you'!
 
      if (application_read_strobe='1' and application_port_id(1 downto 0)="10") then 
        read_link_fifo <= '1';
       else 
        read_link_fifo <= '0';
      end if;

    end if;

  end process application_input_ports;

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- FIFO buffer to pass messages from security processor to application processor  
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- Being able to pass messages enables the application software to also have authentication features.  
  --
  --

  link_fifo: bbfifo_16x8 
  port map (       data_in => security_out_port,
                  data_out => link_fifo_data,
                     reset => reset_link_fifo,              
                     write => write_link_fifo,
                      read => read_link_fifo,
                      full => link_fifo_buffer_full,
                 half_full => link_fifo_half_full,
              data_present => link_fifo_data_present,
                       clk => clk);


  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- THE DESIGN AUTHENTICATION SECURITY 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- The following logic defines the authentication process for the 'real design'.
  -- Remember that this authentication design has demonstration and evaluation properties which add to the size and 
  -- complexity normally required. In practice, all efforts should be made to hide the authentication algorithm and 
  -- prevent it being reverse engineered.
  --
  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Communication with StrataFLASH memory   
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- The StrataFLASH memory is critical to the authentication process. The unique serial number in the device 
  -- forms the basis for anti-cloaning by computing an authentication value derived from that serial number and 
  -- storing it somewhere else in the non volatile memory. So only if the stored authentication value 
  -- corresponds with the unique serial number will the design be authorised to operate. Only by knowing the 
  -- authentication algorithm can other FLASH memories be programmed with the appropriate authentication value. 
  --
  --
  -- The StrataFLASH memory can be used in 8-bit or 16-bit modes. Since PicoBlaze is an 8-bit 
  -- processor, this design forces the 8-bit data mode. As a result, the 128Mbit memory is organised 
  -- as 16,777,216 bytes accessed using a 24-bit address (000000 to FFFFFF hex).
  --
  strataflash_byte <= '0';
  --
  --
  -- To read the StrataFLASH memory the output enable (OE) signal must be driven Low on the memory and 
  -- the pins on the Spartan-3E must become inputs (i.e. the output buffers must be high impedance).
  --
  --
  strataflash_oe <= not(strataflash_read);  --active Low output enable
  --
  strataflash_d <= write_data when (strataflash_read='0') else "ZZZZZZZZ";
  --
  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- LCD interface  
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- The 4-bit data port is bidirectional with 'lcd_rw' High for reading and Low for writing. 
  -- 'lcd_drive' is a signal in this design that acts as an LCD master enable signal. When Low it which prevents either the 
  -- FPGA outputs or the LCD display from driving the data lines which could otherwise be in contention with the StrataFLASH
  -- (This is really to facilitate design reuse should the StrataFLASH be accessed in 16-bit mode in a different design).
  --
  --Control of read and write signal
  lcd_rw <= lcd_rw_control and lcd_drive;

  --use read/write control to enable output buffers.
  lcd_d <= lcd_output_data when (lcd_rw_control='0' and lcd_drive='1') else "ZZZZ";

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- UART  
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- Connect the 8-bit, 1 stop-bit, no parity transmit and receive macros.
  -- Each contains an embedded 16-byte FIFO buffer.
  --

  transmit: uart_tx 
  port map (              data_in => security_out_port, 
                     write_buffer => write_to_uart,
                     reset_buffer => '0',
                     en_16_x_baud => en_16_x_baud,
                       serial_out => tx_female,
                      buffer_full => tx_full,
                 buffer_half_full => tx_half_full,
                              clk => clk );


  receive: uart_rx
  port map (            serial_in => rx_female,
                         data_out => rx_data,
                      read_buffer => read_from_uart,
                     reset_buffer => '0',
                     en_16_x_baud => en_16_x_baud,
              buffer_data_present => rx_data_present,
                      buffer_full => rx_full,
                 buffer_half_full => rx_half_full,
                              clk => clk );  
  
  --
  -- Set baud rate to 9600 for the UART communications
  -- Requires en_16_x_baud to be 153600Hz which is a single cycle pulse every 326 cycles at 50MHz 
  --

  baud_timer: process(clk)
  begin
    if clk'event and clk='1' then

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?