• No results found

5 DESIGN AV FIR-FILTER

6.3 PS/2 PORT

7.3.5 Filter_muls

Det finns tre sådana block och i dessa sker multiplikationerna av

filterkoefficienterna och insignal.

När signalen load är låg så laddas x_in och c_in i x- respektive c-registret.

Sedan sker multiplikationen mellan dessa värden och produkten läggs på

utsignalen y1. När en multiplikation är klar så skickas en ready signal.

Figur 7.6

7.3.6

Adder

Ready signalen i detta block är sammankopplad med ready signalen från

multiplier modulen. När denna signal blir låg så sparas det tidigare inkommande

värdet z_in i register s. Efter att detta har inträffats så adderas värdet i register s

och in_add. Efter denna addition läggs summan ut på utsignalen ut.

7.3.7

Adder2

Adder2 fungerar på liknade sätt som adder men den har ingen ready signal. Det

gör att ett inkommande värde(z_in) sparas i register s utan att någon ready

signal sätts. Sedan läggs produkten från multiplier på in_add och adderas till sist

med värdet i s och läggs på utsignalen ut.

Figur 7.8

7.3.8

Store

I detta block skall produkten av x_in. När signalen ready är låg så sparas det

inkommande värdet från in_data i register z. Därefter så läggs värdet ut på

utsignalen ut_data.

8

Avslutning

I detta avsnitt diskuteras arbetet och resultaten redovisas.

8.1

Resultat CORDIC

Simuleringarna utförda i Matlab skilde sig jämfört med resultaten från

utförandet på XSA-50 kortet.

Andledningen till detta är att hårdvaruutförandet av CORDIC-framåtrotationen

bara kan utföra ett fåtal iterationer, så kan det uppstå vissa felaktigheter. De

uppmätta värdena från hårdvaruutförandet av programmet kan även skilja sig

från de simulerade värdena på grund av avrundningsfel. Detta beror på att man i

hårdvaran endast kan jobba med heltal.

Matlabprogram som har skrivits skapar den nödvändiga HEX filen, som behövs

för att ladda ner det valda x-värdet på SDRAM:en. Detta underlättar då man

slipper räkna ut checksumovärdena som är nödvändiga.

Vidare har det skapts en manual som kan användas vid självstudier av bland

annat implementering av CORDIC-algoritmen och SDRAM funktionen på

XSA-50 kortet.

8.2

Resultat FIR

Efter att simuleringsresultatet i Matlab har jämförts med det på hårdvaran så

kunde det konstateras att implementeringen var lyckad. Filtret fungerade enligt

förutsättningarna.

Utsignalen y[n] visades på olika sätt vid simulering respektive

hårdvaruimplementering. I Matlab visades multiplikationerna av insignalen och

filterkoefficienterna var för sig. Medan det på hårdvaran är summan av samtliga

multiplikationer som visas.

Vidare har det skapts en manual som kan användas vid självstudier av bland

annat implementering av FIR-filter och tangentbordsfunktionen på XSA-50

kortet.

8.3

Problem

8.4

Diskussion

CORDIC-algoritmen är väl anpassad till att användas på DSP tillämpningar. Då

den till största delen handlar om addition och skiftoperationer. I detta arbete så

har algoritmen anpassats till att fungerar med XSA-50 kortet. Detta har fungerat

väl då laborationskortet har många funktioner som kan utnyttjas. I CORDIC

tillämpningen så används den inbyggda SDRAM:en. Genom att utgå från detta

projekt kan man lätt använda SDRAM till egna projekt och tillämpningar.

Vid konstruktionen av FIR filtret så utfördes simulation i Matlab, detta

underlättade vidare arbete med konstruktionen på XSA-50 kortet.

Blockkonstruktion tillämpades med stor fördel. Detta gjorde det mycket enklare

att skapa en bra översikt över de olika delarna i filtret. Felsökning av FIR filtret

underlättades avsevärt, då varje block kunde simuleras var för sig. För denna

del av projektet har PS/2 ingången använts för inläsning ifrån tangentbordet.

Detta projekt kan vara en utgångspunkt för att anpassa tangentbordsinläsning

till egna tillämpningar.

9

Terminologi

Akrynom

Förklaring

CLB

Configurable Logic Block

CORDIC

COordinate Rotation DIgital Computer

CS

Carry Signal

DCORDIC

Differential CORDIC

DFT

Discrete Fourier Transform

DSP

Digital Signal Processor

DTFT

Discrete Time Fourier Transform

FA

Full Adder

FFT

Fast Fourier Transform

FIR

Finite Impulse Response

FPGA

Field Programmable Gate Array

IIR

Infinite Impulse Response

IOB

Input Output Block

LSB

Least Significant Bit

LTI

Linear Time Invariant

LUT

Look-Up Tables

MSB

Most Significant Bit

10

Referenser

1. J.E. Volder, "The CORDIC Trigonometric Computing Technique," IRE

Trans Electronic Computers, vol8, pp. 330-334, Sept. 1959.

2. J. S. Walther, "A Unified Algorithm for Elementary Functions," Proc.

Spring. Joint Computer Conf., pp. 379-385, 1971.

3. R. Andraka, “A Survey of CORDIC Algorithms for FPGAs,” in

Proceedings of the 1998 ACM/SIGDA Sixth International Symposium on

Field Programmable Gate Arrays (FPGA ’98),Monterey, CA, Feb. 22–24,

1998, pp. 191–200.

4. J.E. Volder, ”The Birth of CORDIC”, 2000

5. D. Timmermann (1990): “CORDIC-Algorithmen, Architekturen und

monolithische Realisierungen mit Anwendungen in der Bildverarbeitung,”

Ph.D. thesis, VDI/Springer, Düsseldorf, Vol. 10, No. 152

6. H. Hahn (1991): “Untersuchung und Integration von Berechnungsverfahren

elementarer Funktionen auf CORDIC-Basis mit Anwendungen in der

adaptiven Signalverarbeitung,” Ph.D. thesis, VDI/Springer, Düsseldorf, Vol.

9, No. 125

7. U. Meyer-Bäse: The Use of Complex Algorithm in the Realization of

Universal Sampling Receiver Using FPGAs (in German) (VDI/Springer,

Düsseldorf, 1995), Vol. 10, No.404, 215 pages

8. U. Meyer-Bäse, A. Meyer-Bäse, W. Hilberg: “ COordinate Rotation DIgital

Computer (CORDIC) Synthesis for FPGA,” Lecture Notes in Computer

Science 849, 397-408 (Springer, Heidelberg, 1994)

9.

J. Valls, M. Kuhlmann, K.K. Parhi, “Evaluation of CORDIC Algorithms for

FPGA Design,“ Journal of VLSI Signal Processing 32, pp. 207-222, 2002.

10.

H. Dawid and H. Meyr, “The Differential CORDIC Algorithm: Constant

Scale Factor Redundant Implementation without Correcting Iterations,”

12.

N. Takagi, T. Asada, and S.Yajima, “Redundant CORDIC Methods with a

Constant Scale Factor for Sine and Cosine Computation,” IEEE

Transactions on Computers, vol. 40, no. 9, 1991.

13.

J.-A. Lee andT. Lang, “Constant-Factor RedundantCORDICfor Angle

Calculation and Rotation,” IEEE Transactions on Computers, vol. 41, no. 8,

1992.

14.

Shen-Fu Hsiao and Jean-Marc Delosme, “Householder CORDIC

Algorithm,” IEEE Transactions on Computers, vol. 44, no. 8, 1995.

15.

Shen-Fu Hsiao and Jen-Yin Chen, “Design, Implementation and Analysis of

aNewRedundant CORDIC Processor with Constant Scaling Factor and

Regular Structure,” Journal of VLSI Signal Processing, vol. 20, 1998, pp.

267–278.

16.

Shen-Fu, Hsiao, “A High-Speed Constant-Factor Redundant CORDIC

Processor without Extra Correcting or Scaling Iterations,” in IEEE Int. Conf.

On Circuits and Systems (ISCAS’99), Florida, 1999.

17.

H. Dawid and H. Meyr, “The Differential CORDIC Algorithm: Constant

Scale Factor Redundant implementation without Correcting Iterations,”

IEEE Transactions on Computers, vol. 45, no. 3, 1996.

18.

M. Kuhlmann and K.K. Parhi, “A High-Speed CORDIC Algorithm and

Architecture for DPS Applications,” in Proc. of the 1999 IEEE Workshop

on Signal Processing Systems (SiPS’99), Taipei, Taiwan, Oct. 1999.

19.

M. Kuhlmann and K.K. Parhi, “A New CORDIC Rotation Method for

Generalized Coodinate Systems,” in Proc. of the 1999 Asilomar Conference

on Signal, Systems and Computers, Pacific Grove, CA, Oct. 1999.

20.

P.A. Lynn, W. Fuerst, ”Introductory Digital Signal Processing” 1994

21.

R.M. Mersereau, M.J.T. Smith, ”Digital Filtering” 1994

22.

U.M. Baese,”Dgital Signal Processing with Field Programmable Gate

Arrays” 2001

23.

O. Pedersen, ”Signaler och System kompendium för teori och praktik”, mars

2003, 2:a editionen.

-- Filename Ps2_kbd.vhd

--- -- This circuit accepts a serial datastream and clock from a PS/2 keyboard

-- and outputs the scancode for any key that is pressed. --

-- Notes: --

-- 1. The clock from the PS/2 keyboard does not drive the clock inputs of -- any of the registers in this circuit. Instead, it is sampled at the

-- frequency of the main clock input and edges are extracted from the samples. -- So you have to apply a main clock that is substantially faster than

-- the 10 KHz PS/2 clock. It should be 200 KHz or more. --

-- 2. The scancode is only valid when the ready signal is high. The scancode -- should be registered by an external circuit on the first clock edge -- after the ready signal goes high.

--

-- 3. The ready signal pulses only after the key is released. --

-- 4. The error flag is set whenever the PS/2 clock stops pulsing and the -- PS/2 clock is either at a low level or less than 11 bits of serial -- data have been received (start + 8 data + parity + stop). The circuit -- locks up once an error is detected and will not resume operation until -- a reset is applied. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; package ps2_kbd_pckg is component ps2_kbd generic(

FREQ : natural := 100_000 -- frequency of the main clock (KHz) );

port(

clk : in std_logic; -- main clock

rst : in std_logic; -- asynchronous reset

ps2_clk : in std_logic; -- clock from keyboard

ps2_data : in std_logic; -- data from keyboard

scancode : out std_logic_vector(7 downto 0); -- key scancode

rdy : out std_logic; -- scancode ready pulse

error : out std_logic -- error receiving scancode

);

end component ps2_kbd; end package ps2_kbd_pckg;

library IEEE;

scancode : out std_logic_vector(7 downto 0); -- key scancode rdy : out std_logic; -- scancode ready pulse error : out std_logic -- error receiving scancode );

end entity ps2_kbd;

architecture arch of ps2_kbd is

--constant FREQ : natural := 100_000; constant YES : std_logic := '1'; constant NO : std_logic := '0';

constant PS2_FREQ : natural := 10; -- keyboard clock frequency (KHz) constant TIMEOUT : natural := FREQ / PS2_FREQ; -- ps2_clk quiet timeout

constant KEY_RELEASE : std_logic_vector(7 downto 0) := "11110000"; -- scancode sent when key is released

signal timer_x, timer_r : natural range 0 to TIMEOUT; -- counts time since last PS/2 clock edge signal bitcnt_x, bitcnt_r : natural range 0 to 11; -- counts number of received scancode bits signal ps2_clk_x, ps2_clk_r : std_logic_vector(5 downto 1); -- PS/2 clock synchronization / edge detect

-- shift register

signal ps2_clk_fall_edge : std_logic; -- pulses on falling edge of PS/2 clock signal ps2_clk_rise_edge : std_logic; -- pulses on rising edge of PS/2 clock signal ps2_clk_edge : std_logic; -- pulses on either edge of PS/2 clock signal ps2_clk_quiet : std_logic; -- pulses when no edges on PS/2 clock for TIMEOUT signal sc_x, sc_r : std_logic_vector(9 downto 0); -- scancode shift register

signal keyrel_x, keyrel_r : std_logic; -- this flag is set when the key release scancode is received signal scancode_rdy : std_logic; -- indicates when any scancode has been received

signal rdy_x, rdy_r : std_logic; -- this flag is set when scancode for the pressed key is ready signal error_x, error_r : std_logic; -- this flag is set when an error occurs

begin

-- shift the level on the PS/2 clock into a shift register ps2_clk_x <= ps2_clk_r(4 downto 1) & ps2_clk;

-- look at the PS/2 clock levels stored in the shift register and find rising or falling edges ps2_clk_fall_edge <= YES when ps2_clk_r(5 downto 2) = "1100" else NO;

ps2_clk_rise_edge <= YES when ps2_clk_r(5 downto 2) = "0011" else NO; ps2_clk_edge <= ps2_clk_fall_edge or ps2_clk_rise_edge;

-- shift the keyboard scancode into the shift register on the falling edge of the PS/2 clock sc_x <= ps2_data & sc_r(9 downto 1) when ps2_clk_fall_edge = YES else sc_r;

-- clear the timer right after a PS/2 clock edge and then keep incrementing it until the next edge timer_x <= 0 when ps2_clk_edge = YES else timer_r + 1;

-- indicate when the PS/2 clock has stopped pulsing and is at a high level.

ps2_clk_quiet <= YES when timer_r = TIMEOUT and ps2_clk_r(2) = '1' else NO;

-- increment the bit counter on each falling edge of the PS/2 clock.

-- reset the bit counter if the PS/2 clock stops pulsing or if there was an error receiving the scancode. -- otherwise, keep the bit counter unchanged.

NO when rdy_r = YES or error_r = YES else keyrel_r;

-- the scancode for the pressed key arrives after receiving the key-release scancode rdy_x <= YES when keyrel_r = YES and scancode_rdy = YES else NO;

-- indicate an error if the clock is low for too long or if it stops pulsing in the middle of a scancode error_x <= YES when (timer_r = TIMEOUT and ps2_clk_r(2) = '0') or

(ps2_clk_quiet = YES and bitcnt_r/=11 and bitcnt_r/=0) else error_r;

scancode <= sc_r(scancode'range); -- output scancode

-- parity <= sc_r(scancode'high+1); -- output parity bit for the scancode

-- busy <= YES when bitcnt_r/=0 else NO; -- output busy signal when receiving a scancode rdy <= rdy_r; -- output scancode ready flag

error <= error_r; -- output error flag

-- update the various registers process(rst, clk)

begin

if rst = YES then

ps2_clk_r <= (others => '1'); -- start by assuming PS/2 clock has been high for a while sc_r <= (others => '0'); -- clear scancode register

keyrel_r <= NO; -- key-release scancode has not been received yet rdy_r <= NO; -- no scancodes received yet

timer_r <= 0; -- clear PS/2 clock pulse timer bitcnt_r <= 0; -- clear scancode bit counter error_r <= NO; -- clear any errors

elsif rising_edge(clk) then ps2_clk_r <= ps2_clk_x; sc_r <= sc_x; keyrel_r <= keyrel_x; rdy_r <= rdy_x; timer_r <= timer_x; bitcnt_r <= bitcnt_x; error_r <= error_x; end if; end process;

end architecture arch;

--- --Filename Keyb_scan.vhd --- -- tangentbordsavkodning. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

error : in std_logic;

x_ut : out std_logic_vector (7 downto 0)); end keyb_scan;

architecture Behavioral of keyb_scan is constant YES : std_logic := '1'; constant NO : std_logic := '0';

constant DIG_1 : std_logic_vector(7 downto 0) := "00000001"; constant DIG_2 : std_logic_vector(7 downto 0) := "00000010"; constant DIG_3 : std_logic_vector(7 downto 0) := "00000011"; constant DIG_4 : std_logic_vector(7 downto 0) := "00000100"; constant DIG_5 : std_logic_vector(7 downto 0) := "00000101"; constant DIG_6 : std_logic_vector(7 downto 0) := "00000110"; constant DIG_7 : std_logic_vector(7 downto 0) := "00000111"; constant DIG_8 : std_logic_vector(7 downto 0) := "00001000"; constant DIG_9 : std_logic_vector(7 downto 0) := "00001001"; constant DIG_0 : std_logic_vector(7 downto 0) := "00000000"; constant LETTER_E : std_logic_vector(7 downto 0) := "00000000";

signal s_x : std_logic_vector(7 downto 0);

begin

s_x <= DIG_1 when scancode = "00010110" else DIG_2 when scancode = "00011110" else

DIG_3 when scancode = "00100110" else DIG_4 when scancode = "00100101" else DIG_5 when scancode = "00101110" else DIG_6 when scancode = "00110110" else DIG_7 when scancode = "00111101" else DIG_8 when scancode = "00111110" else DIG_9 when scancode = "01000110" else DIG_0 when scancode = "01000101" else LETTER_E;

process(clk) begin

if rising_edge(clk) then if rdy = YES then

x_ut<=s_x; -- update the display each time a scancode is received end if; end if; end process; end Behavioral; --- --Filename loadbuff.vhd --- -- laddar in alla koefficienter och invärdet från tangentbordet.

library IEEE;

Port ( clk : in std_logic; load : in std_logic; res : in std_logic;

x_in : in std_logic_vector(7 downto 0); x_ut : out std_logic_vector(7 downto 0); c_ut1 : out std_logic_vector(7 downto 0); c_ut2 : out std_logic_vector(7 downto 0); c_ut3 : out std_logic_vector(7 downto 0); ready : out std_logic);

end loadbuff;

architecture Behavioral of loadbuff is

signal c_in1,c_in2,c_in3 : std_logic_vector(7 downto 0); begin

process(res,clk) begin

if res='1' and load=’0’ then -- när res är hög så sätt samtliga koefficienter ready<='1';

c_in1 <="00000001"; c_in2 <="00000010"; c_in3 <="00000001";

c_ut1 <="00000000"; -- och alla utvärden nollställs c_ut2 <="00000000";

c_ut3 <="00000000"; x_ut <="00000000";

elsif clk='1' and clk'event then

if load='1' and res=’0’ then -- när load är hög så ladda koefficienterna och

c_ut1 <=c_in1; -- värdet från tangentbordet in i registerna

c_ut2 <=c_in2; c_ut3 <=c_in3; x_ut <=x_in; ready<='0';

elsif load=’0’ and res=’0’ then ready<='1'; end if; end if; end process; end Behavioral; --- --Filename filter+muls.vhd --- -- multiplicerar koefficienten med invärdet.

library IEEE;

use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM;

architecture Behavioral of filter_muls is type state_type is (s0, s1, s2, s3, s4);

signal state: state_type;

signal c,x: std_logic_vector(7 downto 0);

begin

process(res,clk)

variable p: std_logic_vector(15 downto 0); variable t : std_logic_vector(7 downto 0);

variable count : integer range 0 to 7;

begin

if res ='1' then -- när res är hög så nollställs registerna

x<="00000000"; c<="00000000";

y1<="0000000000000000"; elsif clk = '1' and clk'event then

if load='0' then -- när load är låg så laddas x och c registerna

x<=x_in; c<=c_in; state<=s1; else case state is when s0=> ready<='1'; state<=s0;

when s1 => -- påbörja multiplicering

state <= s2; count :=0; p :="0000000000000000"; t :=x; when s2 => if count = 7 then state <= s3; else if c(count) = '1' then p := p + t; end if; t := t+t; count := count +1; state <= s2; end if; when s3 => ready<='0'; y1<=p; state <= s4; when s4 => state <=s0; end case;

use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM;

--use UNISIM.VComponents.all;

entity adder is

Port ( in_add : in std_logic_vector(15 downto 0); res : in std_logic;

z_in : in std_logic_vector(16 downto 0); ut : out std_logic_vector(17 downto 0); ready : in std_logic;

clk : in std_logic); end adder;

architecture Behavioral of adder is signal s : std_logic_vector(16 downto 0); begin

process(clk,res) begin

if res ='1' then

s<="00000000000000000"; -- när res är hög så nollställs s-registret

elsif clk='1' and clk'event then

if ready='0' then -- när ready är låg så sparas det tidigare värdet i s

s<=z_in; end if;

ut <=s+in_add; -- adderar invärdet och s samt lägger på utgång

end if; end process; end Behavioral; --- --Filename adder2.vhd --- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM;

--use UNISIM.VComponents.all;

entity adder2 is

Port ( in_add : in std_logic_vector(15 downto 0); Res : in std_logic;

z_in : in std_logic_vector(15 downto 0); ut : out std_logic_vector(16 downto 0);

s<=z_in;

ut <=s+in_add; -- adderar och lägger ut på utgången

end if; end process; end Behavioral; --- --Filename store.vhd --- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; entity store is Port ( clk : in std_logic; ready : in std_logic; res : in std_logic;

in_data : in std_logic_vector(15 downto 0); ut_data : out std_logic_vector(15 downto 0)); end store;

architecture Behavioral of store is signal z: std_logic_vector(15 downto 0); begin

process(clk,res) begin

if res ='1' then -- när res är hög så nollställs z registret

z<="0000000000000000"; elsif clk='1' and clk'event then

if ready='0' then -- när ready är låg sparas invärdet i z

z<=in_data; end if;

ut_data<=z; -- lägger ut z på utgången

end if;

end process; end Behavioral;

--- -- Filename: sdramtst50.vhd

---

library IEEE, UNISIM; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use UNISIM.VComponents.all; use WORK.common.all; use WORK.mem.all; use WORK.xsasdram.all;

-- synchronous DRAM tester

entity sdramTst50 is

generic(

FREQ: natural := 100_000; -- frequency of operation in KHz

PIPE_EN: boolean:= TRUE; -- enable fast, pipelined SDRAM operation

DATA_WIDTH:natural := 16; -- SDRAM data width

BEG_ADDR: natural := 16#00_0000#; -- beginning SDRAM address END_ADDR: natural := 16#3F_FFFF#; -- ending SDRAM address BEG_TEST: natural := 16#00_0000#; -- beginning test range address END_TEST: natural := 16#3F_FFFF# -- ending test range address );

port(

ce_n: out std_logic; -- Flash RAM chip-enable

pushb_n: in std_logic; -- active-low pushbutton input

clk: in std_logic; -- main clock input from external clock source sclkfb: in std_logic; -- feedback SDRAM clock with PCB delays sclk: out std_logic; -- clock to SDRAM

cke: out std_logic; -- SDRAM clock-enable

cs_n: out std_logic; -- SDRAM chip-select

ras_n: out std_logic; -- SDRAM RAS

cas_n: out std_logic; -- SDRAM CAS

we_n: out std_logic; -- SDRAM write-enable

ba: out unsigned( 1 downto 0); -- SDRAM bank-address

sAddr: out unsigned(11 downto 0); -- SDRAM address bus sData: inout unsigned(DATA_WIDTH-1 downto 0); -- data bus to/from

-- SDRAM

dqmh: out std_logic; -- SDRAM DQMH

dqml: out std_logic; -- SDRAM DQML

s: out unsigned(6 downto 0); -- 7-segment LED

pps: out std_logic_vector(6 downto 3) -- outputs to parallel port -- status bits

);

end sdramTst50;

signal hAddr: unsigned(ADDR_WIDTH-1 downto 0); -- host address bus

signal hDIn: unsigned(DATA_WIDTH-1 downto 0); -- host-side data to SDRAM signal hDOut: unsigned(DATA_WIDTH-1 downto 0); -- host-side data from SDRAM

signal rd: std_logic; -- host-side read control signal

signal wr: std_logic; -- host-side write control signal

signal dataIn: unsigned(DATA_WIDTH-1 downto 0); -- input databus from SDRAM signal dataOut: unsigned(DATA_WIDTH-1 downto 0); -- output databus to SDRAM signal divCnt: unsigned(22 downto 0); -- clock divider

signal progress: std_logic_vector(1 downto 0); -- test progress indicator

Related documents