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 + -
显示快捷键?