§ Главный шаблон
Скачать весь шаблон можно тут.1module max2 2( 3 input clock, 4 input [3:0] key, 5 inout [7:0] led, 6 inout [9:0] f0, 7 inout [9:0] f1, 8 inout [9:0] f2, 9 inout [9:0] f3, 10 inout [9:0] f4, 11 inout [9:0] f5, 12 inout dp, 13 inout dn, 14 inout pt 15); 16 17assign f0 = 10'hz; assign f1 = 10'hz; assign f2 = 10'hz; 18assign f3 = 10'hz; assign f4 = 10'hz; assign f5 = 10'hz; 19 20wire [15:0] datain; 21wire ready; 22 23altufm_reader UFMReaderUnit 24( 25 .osc (osc), 26 .address (9'h1), 27 .datain (datain), 28 .ready (ready) 29); 30 31endmodule
§ Блок AltUFM
Этот блок инициализирует физический модуль ufm.1//synopsys translate_off 2`timescale 1 ps / 1 ps 3 4//synopsys translate_on 5module altufm 6( 7 input arclk, // Запись на позитивном фронте АДРЕС 8 input ardin, // Входящий бит адреса (MSB), первый бит старший 9 input arshft, // =1 последовательная загрузка адреса, =0 то +1 к адресу 10 output busy, // =1 Устройство занято 11 input drclk, // Запись на позитивном фронте ДАННЫХ 12 input drdin, // Входящие бит MSB 13 output drdout, // Исходящий бит MSB 14 input drshft, // =0 @posedge drclk, копирование из/в UFM, =1 вдвиг бита 15 input erase, // =1 очистить блок 16 output osc, // Тактовый осциллятор ~ 5.5 Мгц 17 input oscena, // =1 Разрешение тактового генератора 18 input program, // =1 Программирование UFM 19 output rtpbusy // =1 Устройство занято программированием 20); 21 22maxii_ufm maxii_ufm_block1 23( 24 .arclk (arclk), 25 .ardin (ardin), 26 .arshft (arshft), 27 .bgpbusy (rtpbusy), 28 .busy (busy), 29 .drclk (drclk), 30 .drdin (drdin), 31 .drdout (drdout), 32 .drshft (drshft), 33 .erase (erase), 34 .osc (osc), 35 .oscena (oscena), 36 .program (program), 37 // synopsys translate_off 38 .ctrl_bgpbusy (1'b0), 39 .devclrn (1'b1), 40 .devpor (1'b1), 41 .sbdin (1'b0), 42 .sbdout () 43 // synopsys translate_on 44); 45 46defparam 47 maxii_ufm_block1.address_width = 9, 48 maxii_ufm_block1.erase_time = 500000000, 49 maxii_ufm_block1.init_file = "ufm.mif", 50 // Копия тестовых данных 1Кб 51 maxii_ufm_block1.mem1 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 52 maxii_ufm_block1.mem2 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 53 maxii_ufm_block1.mem3 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 54 maxii_ufm_block1.mem4 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 55 maxii_ufm_block1.mem5 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 56 maxii_ufm_block1.mem6 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 57 maxii_ufm_block1.mem7 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 58 maxii_ufm_block1.mem8 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 59 maxii_ufm_block1.mem9 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 60 maxii_ufm_block1.mem10 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 61 maxii_ufm_block1.mem11 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 62 maxii_ufm_block1.mem12 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 63 maxii_ufm_block1.mem13 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 64 maxii_ufm_block1.mem14 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 65 maxii_ufm_block1.mem15 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 66 maxii_ufm_block1.mem16 = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 67 maxii_ufm_block1.osc_sim_setting = 180000, 68 maxii_ufm_block1.program_time = 1600000, 69 maxii_ufm_block1.lpm_type = "maxii_ufm"; 70 71endmodule
§ Работа с UFM
Когда приходит сигнал ready, тогда можно установить новый адрес сразу же и получить данные.Top-уровень
1wire [15:0] datain; 2wire ready; 3 4altufm_reader UFMReaderUnit 5( 6 .osc (osc), 7 .address (9'h1), 8 .datain (datain), 9 .ready (ready) 10);Модуль считывания
1module altufm_reader 2( 3 output osc, // Осциллятор 4 input [8:0] address, // Заданный адрес 5 output reg [15:0] datain, // Полученные данные 6 output ready // Признак готовности данных 7); 8 9assign ready = (cnt == 27); 10reg [4:0] cnt = 1'b0; 11reg ardin = 1'b0; 12reg drshft = 1'b0; 13wire drdout; 14 15altufm AltUFMUnit 16( 17 .arclk (osc), 18 .drclk (osc), 19 .drdin (1'b0), // Данные для программирования Flash 20 .drdout (drdout), // Выходные данные 21 .drshft (drshft), // 0: Защелка, 1: Задвижка 22 .ardin (ardin), // Данные для адреса 23 .arshft (1'b1), // Всегда последовательный адрес 24 .oscena (1'b1), // Активировать осциллятор 25 .osc (osc) // Осциллятор 5.56 Мгц 26); 27 28always @(posedge osc) 29begin 30 31 cnt <= cnt + 1; 32 drshft <= cnt > 9; 33 ardin <= cnt < 9 ? address[8 - cnt] : 1'b0; 34 datain <= {datain[14:0], drdout}; 35 36 // Данные готовы 37 if (ready) cnt <= 0; 38 39end 40 41endmodule
§ Эмулятор UFM
Здесь osc — это input-провод, поскольку osc задается в tb.v1module altufm 2( 3 input wire oscena, 4 input wire osc, 5 6 input wire arclk, 7 input wire ardin, 8 input wire arshft, 9 10 input wire drclk, 11 input wire drdin, 12 input wire drshft, 13 output wire drdout, 14 15 input wire prgram 16); 17 18// --------------------------------------------------------------------- 19reg [15:0] ufm[512]; 20initial begin $readmemh("ufm.hex", ufm, 0); end 21// --------------------------------------------------------------------- 22 23assign drdout = datareg[15]; 24 25// 512 x 16 = 1024 байт памяти 26reg [ 8:0] address; 27reg [15:0] datareg; 28 29// Вдвиг адреса или увеличение на +1 30always @(posedge arclk) 31 address <= arshft ? {address[7:0], ardin} : address + 1; 32 33always @(posedge drclk or posedge prgram) 34if (prgram) 35 ufm[address] <= datareg; 36else if (drshft) 37 datareg <= {datareg[14:0], drdin}; 38else 39 datareg <= ufm[address]; 40 41endmodule