Đoạn mã VHDL

Một phần của tài liệu ĐỒ án môn học THIẾT kế MẠCH TÍCH hợp số thiết kế máy phát nhạc MP3, WAV sử dụng KIT phát triển NB2DSK01 và phần mềm hỗ trợ altium designer (Trang 63 - 79)

---CT chinh Bai tap thiet ke mach logic to hop---

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ND30to80 is

port ( X_3,X_2,X_1,X_0: in std_logic; F : out std_logic );

end ND30to80;

architecture dataflow of ND30to80 is

begin

F <= '1' when (X_3='0'and X_2='1' and X_1='0'and X_0='0')

else

'1' when (X_3='0'and X_2='1' and X_1='0'and X_0='1')

else

'1' when (X_3='0'and X_2='1' and X_1='1'and X_0='0') else '1' when (X_3='0'and X_2='1' and X_1='1'and X_0='1') else

'1' when (X_3='1'and X_2='0' and X_1='0'and X_0='0') else '1' when (X_3='1'and X_2='0' and X_1='0'and X_0='1') else '1' when (X_3='1'and X_2='0' and X_1='1'and X_0='0') else '1' when (X_3='1'and X_2='0' and X_1='1'and X_0='1') else

'1' when (X_3='1'and X_2='1' and X_1='0'and X_0='0') else '0';

end dataflow;

---

---Testbench cua Bai tap thiet ke mach logic to hop---

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

---

entity ND30to80_test is

end ND30to80_test;

---

architecture test of ND30to80_test is type sample is record

X_3,X_2,X_1,X_0, F: std_logic; end record sample;

type sample_array is array (natural range <>) of sample; constant test_data: sample_array :=

( ('0','0','0','0','0'),('0','0','0','1','0'),('0','0','1','0','0'), ('0','0','1','1','0'),('0','1','0','0','1'),('0','1','0','1','1'), ('0','1','1','0','1'),('0','1','1','1','1'),('1','0','0','0','1'), ('1','0','0','1','1'),('1','0','1','0','1'),('1','0','1','1','1'), ('1','1','0','0','1'),('1','1','0','1','0'),('1','1','1','0','0'), ('1','1','1','1','0') );

component ND30to80 is

port (X_3,X_2,X_1,X_0 : in std_logic; F : out std_logic

);

end component;

--- khai bao cac tin hieu vao ra cho DUT---

signal X_3in,X_2in,X_1in,X_0in,Fout : std_logic;

begin

process begin

for i in test_data'range loop X_3in <= test_data(i).X_3; X_2in <= test_data(i).X_2; X_1in <= test_data(i).X_1; X_0in <= test_data(i).X_0; wait for 10 ns; end loop; wait; end process;

DUT:ND30to80 port map(X_3in, X_2in,X_1in, X_0in, Fout);

end;

PHỤ LỤC B THIẾT KẾ MẠCH LOGIC TUẦN TỰ

B.1 Mô tả bài toán

Thiết kế mạch tích hợp số thực hiện chức năng của một T-FF đầy đủ các chân T, Q, Qnot, CLK sườn dương, CLR và PR tích cực mức cao bằng công nghệ FPGA.

B.2 Các bước thực hiện

Đối với bài toán thiết kế mạch logic tuần tự, ta đi thực hiện các bước tương tự như bài toán thiết kế mạch logic tổ hợp để thu được kết quả cuối cùng.

Bước 1: Tạo một dự án FPGA mới

- Đầu tiên, mở Altium, để tạo một Project mới ta vào File New Project. - Chọn FPGA project đặt tên cho Project, chọn vị trí lưu nhấn OK

Bước 2: Tạo File VHDL

- Nếu chưa có file sẵn trong thư mục, ta đi tạo một file VHDL mới bằng Với cách cách kích chuột phải vào dự án FPGA vừa tạo add new to project VHDL document.

- Nếu đã có sẵn file bạn chỉ việc thêm file đó vào dự án bằng cách kích chuột phải vào dự án FPGA vừa tạo add Exiting to project đi đến thư mục bạn lưu file và ấn chọn

Bước 3: Tạo đoạn mã VHDL

Gõ đoạn mã chương trình sau vào không gian làm việc của file VHDL

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

---thuc the---

entity T_FF is

Port ( T, CLK, CLR,PR : in STD_LOGIC; Q, Qnot : out STD_LOGIC);

end T_FF;

---kien truc---

architecture BHV of T_FF is

begin

process (T, CLK, CLR, PR) VARIABLE TEMP:STD_LOGIC:='0';

begin

if (CLR = '1') then TEMP := '0';

elsif( PR = '1') then TEMP := '1';

TEMP := not TEMP; end if; end if; Q<= NOT TEMP; Qnot<= TEMP; end process; end BHV;

Bước 4: Biên dịch chương trình

- Sau khi soạn thảo code xong ta lưu file lại sau đó ấn chuột phải vào tên file và ấn Compile để kiểm tra xem file lỗi hay không.

Bước 5: Tạo file Nguyên lý

- Chọn add new to project => Schematic. Sau đó ở cửa sổ shematic ta ấn chuột phải chọn Sheet Action => Create Sheet Symbol From Sheet HDL.

- Chọn file HDL đã lưu trước đó ta thu được Symbol và đồng thời ta sẽ lấy các Deepswit và LED trong thư viện của Altium. Sửa tên của các DW, LED và nối với các chân trên symbol.

- Từ thư viện FPGA NB2DSK01 Port-Plugin.InLib, lấy ra các nút bấm và các Led

Hình B 1. Thao tác lấy các nút bấm và Led - Từ thư viện FPGA Generic.InLib, lấy ra bộ chia tần CDIV256

Hình B 2. Thao tác lấy bộ chia tần

Hình B 3. Sơ đồ nguyên lý hoàn chỉnh của T_FF

- Lưu file Schematic lại và chuột phải vào tên file Schematic ấn compile. Sau đó lưu project và chuột phải vào project và ấn compile

Bước 6: Nạp KIT B.3 Đoạn mã VHDL

---CT chinh T_FF--- ---khai bao thu vien---

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

---thuc the---

entity T_FF is

Port ( T, CLK, CLR,PR : in STD_LOGIC; Q, Qnot : out STD_LOGIC);

end T_FF;

---kien truc---

architecture BHV of T_FF is

begin

process (T, CLK, CLR, PR) VARIABLE TEMP:STD_LOGIC:='0';

begin

if (CLR = '1') then TEMP := '0';

elsif( PR = '1') then TEMP := '1';

elsif (rising_edge(CLK)) then if(T ='1') then

TEMP := not TEMP; end if; end if; Q<= NOT TEMP; Qnot<= TEMP; end process; end BHV; ---Test T_FF--- library ieee;

use ieee.std_logic_1164.all;

---

entity testbench is end testbench;

---

architecture test of testbench is type sample is record

CLR : std_logic; PR: std_logic; clk: std_logic; T: std_logic; end record;

type sample_array is array (natural range <>) of sample; constant test_data: sample_array :=

( ('1','0','0','0'), ('0','1','1','0'), ('0','0','0','1'), ('0','0','1','1'), ('0','0','0','0'), ('0','0','1','0'),

('0','0','0','1'), ('0','0','1','1'), ('0','0','0','0'), ('0','0','1','0') ); signal clk,T,PR, CLR: std_logic; signal Q, Qnot: std_logic;

begin

connect: entity work.T_FF port map ( clk => clk, PR =>PR, CLR => CLR, T => T, Q => Q, QNOT => Qnot ); process begin

for i in test_data'range loop CLR <=test_data(i).CLR; PR <=test_data(i).PR; clk <=test_data(i).clk; T <=test_data(i).T; wait for 10 ns; end loop; wait; end process; end test;

PHỤ LỤC C CODE MP3 DECODER ---MAIN C--- #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <fs.h> #include <unistd.h> #include <sys/stat.h>

// Application Stack interface

#include "swplatform.h" #include "form1.h"

#define DIR_SEP "/"

#define FAILED() { printf( "*** Failed ***\n" ); } #define INPUT_SIZE (8 * 1024)

#define ERROR_LIMIT 3 sdcard_t *drv_sdcard;

static int audio_samplerate; static uint16_t *mp3_output_pos; static int mp3_input_bufnr; static int mp3_input_count; static int mp3_output_count; static int mp3_error_count;

// these buffers must be allocated in external memory

uint32_t mp3_input_buf[2][INPUT_SIZE / 4]; uint32_t mp3_output_buf[576];

static int mp3_open(const char *filename);

static int mp3_skip_id3(int infile);

static bool mp3_process(int infile);

static bool mp3_errorreport(void);

static void init( void );

typedef enum { STATE_DETECT, STATE_INIT, STATE_MOUNT, STATE_IDLE, STATE_PLAYING, STATE_RESET } state_t;

/ ******************************************************************** ** |* |* FUNCTION : main |* |* PARAMETERS : None |* |* RETURNS : None |*

|* DESCRIPTION : main program */

void main( void ) {

int handle = 0;

state_t state = STATE_RESET; int partition = 0;

init();

agui_show_form(AGUI_HANDLE(form1)); for (;;)

{

gui_play = false; // set by GUI if 'play' pressed

gui_stop = false; // set by GUI if 'stop' pressed

agui_service(agui);

// guard for card removal

if ((state != STATE_DETECT) && !sdcard_detect(drv_sdcard)) { state = STATE_RESET; } switch (state) { case STATE_RESET:

unmount("/sdcard", MOUNT_FLAG_FORCE); listbox_clear(&form1_dirs); listbox_clear(&form1_files); obj_set_enabled(AGUI_HANDLE(form1_dirs), false); obj_set_enabled(AGUI_HANDLE(form1_files), false); obj_set_enabled(AGUI_HANDLE(form1_play), false); obj_set_enabled(AGUI_HANDLE(form1_stop), false); gui_info("Please insert SD card...");

state = STATE_DETECT; break;

case STATE_DETECT:

if (sdcard_detect(drv_sdcard)) {

gui_info("Initializing card..."); state = STATE_INIT; } break; case STATE_INIT: if (sdcard_device_init(drv_sdcard) == 0) { partition = 1; state = STATE_MOUNT; } break; case STATE_MOUNT:

if (mount("/dev/BLOCKIO", "/sdcard", "fatfs", partition, MOUNT_FLAG_RDONLY) == 0) { dirlisting("/sdcard"); listbox_sort(&form1_dirs, false); obj_set_enabled(AGUI_HANDLE(form1_dirs), true); obj_set_enabled(AGUI_HANDLE(form1_files), true); obj_set_enabled(AGUI_HANDLE(form1_play), false); obj_set_enabled(AGUI_HANDLE(form1_stop), false); gui_info(""); state = STATE_IDLE; } else { switch (partition) {

case 1: partition = 2; break; case 2: partition = 3; break; case 3: partition = 4; break; case 4: partition = 0; break;

default: state = STATE_DETECT; break; } } break; case STATE_IDLE: if (gui_play) {

handle = mp3_open(gui_dir_file); if (!handle) break;

obj_set_enabled(AGUI_HANDLE(form1_dirs), false); obj_set_enabled(AGUI_HANDLE(form1_files), false); obj_set_enabled(AGUI_HANDLE(form1_play), false); obj_set_enabled(AGUI_HANDLE(form1_stop), true); gui_info("Starting play...");

state = STATE_PLAYING; }

case STATE_PLAYING:

if (gui_stop | !mp3_process(handle)) { close(handle); obj_set_enabled(AGUI_HANDLE(form1_dirs), true); obj_set_enabled(AGUI_HANDLE(form1_files), true); obj_set_enabled(AGUI_HANDLE(form1_play), true); obj_set_enabled(AGUI_HANDLE(form1_stop), false); state = STATE_IDLE; } break; default: /* never used */ break; } } } / ******************************************************************** ** |* |* FUNCTION : init |* |* PARAMETERS : None |* |* RETURNS : None |*

|* DESCRIPTION : Initialize hardware and drivers */

static void init( void ) {

puts( "MP3 decoder example, " __FILE__ " compiled " __DATE__ ", " __TIME__ ); mp3dec_set_outputbuffer(drv_mp3dec, mp3_output_buf); drv_sdcard = sdcard_open(DRV_SDCARD); audio_set_volume(audio, 255); } / ******************************************************************** ** |* |* FUNCTION : mp3_open |*

|* PARAMETERS : filename = filename (inculding path) of MP3 to play

|*

|* RETURNS : filehandle |*

|* DESCRIPTION : Prepare to play an MP3 file */

static int mp3_open(const char *filename) {

int infile;

printf("playing '%s'\n", filename); infile = open(filename, O_RDONLY); mp3_error_count = 0; mp3_input_bufnr = 0; mp3_input_count = 0; mp3_output_count = 0; audio_samplerate = 0; mp3_skip_id3(infile); mp3dec_decode(drv_mp3dec, NULL, 0); return infile; } / ******************************************************************** ** |* |* FUNCTION : mp3_skip_id3 |*

|* PARAMETERS : filehandle of file being played |*

|* RETURNS : fileposition or -1 if error |*

|* DESCRIPTION : skip ID3 tag if found at begin of file */

static int mp3_skip_id3(int infile) {

char buf[10], *b = buf; int tagsize = 0;

// read the possile ID3 header

if (read(infile, buf, 10) != 10) goto rewind; // ID3 marker

if (*b++ != 'I') goto rewind; if (*b++ != 'D') goto rewind; if (*b++ != '3') goto rewind; // ignore version & flags

// read 28 bit integer

for (int i = 0; i < 4; ++i) {

if (*b & 0x80) goto rewind;

tagsize = (tagsize << 7) + (int) *b++; }

printf("found ID3 tag, skipping %i bytes\n", 10 + tagsize); return lseek(infile, tagsize, SEEK_CUR);

rewind:

return lseek(infile, 0, SEEK_SET); } / ******************************************************************** ** |* |* FUNCTION : mp3_process |*

|* PARAMETERS : filehandle of file being played |*

|* RETURNS : true while playing, false meaning EOF and decoding is ready

|*

|* DESCRIPTION : Call repeatedly to play the MP3 file */

static bool mp3_process(int infile) {

uint32_t status = mp3dec_get_status(drv_mp3dec); if (status & MP3DEC_STATUS_HEADERREADY)

{

if (mp3_errorreport()) {

if (++mp3_error_count > ERROR_LIMIT) return false; }

}

if ((mp3_output_count == 0) && (status & MP3DEC_STATUS_WRITEREADY))

{

if (mp3_error_count) {

// very crude error handling: discard this frame, tell decoder we want another

// this avoids 'garbage files' to create audio by accident, while minimizing the effect

// on legitimate files with only a few broken frames distributed over the file

mp3dec_decode_continue(drv_mp3dec); --mp3_error_count;

else {

// new decoded frame is ready

int frame_samplerate = mp3dec_get_samplerate(drv_mp3dec);

if (frame_samplerate && (frame_samplerate != audio_samplerate))

{

char buf[64];

audio_set_format(audio, frame_samplerate, 2, 16); audio_samplerate = frame_samplerate;

sprintf(buf, "Playing %i %s\n", frame_samplerate, (mp3dec_get_channelmode(drv_mp3dec) == 1) ? "mono" : "stereo"); gui_info(buf);

}

mp3_output_pos = (uint16_t*) mp3_output_buf; mp3_output_count = 2 * 576;

} }

if (mp3_output_count > 0) {

// play (part of) decoded data

int played = audio_play(audio, mp3_output_pos, mp3_output_count);

if (played < 0) return false; // audio error

mp3_output_pos += played;

if ((mp3_output_count -= played) == 0) {

// tell decoder we want another frame

mp3dec_decode_continue(drv_mp3dec); }

}

if ((mp3_input_count == 0) && (infile != 0)) {

// read new data into the inactive buffer

mp3_input_count = read(infile, mp3_input_buf[mp3_input_bufnr], INPUT_SIZE);

if (mp3_input_count == 0) mp3_input_count = -1; }

if ((mp3_input_count > 0) && (status & MP3DEC_STATUS_READEMPTY)) {

// decoder ran out of input, give it the buffer we read

mp3dec_set_inputdata(drv_mp3dec,

mp3_input_buf[mp3_input_bufnr], mp3_input_count); // swap active/inactive buffer

mp3_input_count = 0; }

if ((mp3_input_count < 0) && (status & MP3DEC_STATUS_READEMPTY) && (mp3_output_count == 0))

{

// no more data to decode or play

gui_info(""); return false; } return true; } / ******************************************************************** ** |* |* FUNCTION : mp3_errorreport |* |* PARAMETERS : None |* |* RETURNS : None |*

|* DESCRIPTION : Test MP3 headerword for unsupported flags */

static bool mp3_errorreport(void) {

uint32_t header = mp3dec_get_header(drv_mp3dec); bool errors = false;

if ((header & 0x00060000) != 0x00020000) { errors = true; gui_info("Error: mp3-layer<>3\n"); }

if ((header & 0x0000F000) == 0x00000000) { errors = true; gui_info("Error: free bitrate\n"); }

if ((header & 0x00080000) != 0x00080000) { errors = true; gui_info("Error: low freq extension\n"); }

if ((header & 0x00000003) != 0x00000000) { errors = true; gui_info("Error: emphasis\n"); }

return errors; } / ******************************************************************** ** |* |* FUNCTION : dirlisting |*

|* PARAMETERS : path: path of the dir |*

|* RETURNS : None |*

|* DESCRIPTION : List the contents of the dir into the GUI */

void dirlisting( const char *path ) {

DIR *dir; struct dirent *dirent; struct stat buf;

char path_to_file[PATH_MAX]; chdir(path);

dir = opendir(path); if ( dir != NULL ) {

printf( "Reading folder \"%s\"\n", path ); listbox_clear(&form1_dirs); listbox_clear(&form1_files); while ( 1 ) { dirent = readdir(dir); if (dirent == NULL) { break; }

sprintf(path_to_file, "%s%s%s", path, DIR_SEP, dirent- >d_name); if (stat(path_to_file, &buf) == 0) { if (S_ISDIR(buf.st_mode)) { if (strcmp(dirent->d_name, ".") == 0) { /* skip */ } else { listbox_add(&form1_dirs, dirent->d_name, NULL); } } else if (S_ISREG(buf.st_mode)) {

listbox_add(&form1_files, dirent->d_name, NULL); }

else {

printf("[UNK]\t%s\n", dirent->d_name); } } else { FAILED(); } } if (closedir(dir) != 0)

{

FAILED(); }

} }

Một phần của tài liệu ĐỒ án môn học THIẾT kế MẠCH TÍCH hợp số thiết kế máy phát nhạc MP3, WAV sử dụng KIT phát triển NB2DSK01 và phần mềm hỗ trợ altium designer (Trang 63 - 79)