CAD FMレシーバ

CAD 最終課題
テーマ : デジタル FM レシーバ
グループ名 :
T シャツ:
取り組んだ課題 :
スピード :
面積 :
共同実験者 :
035734B :
035740F :
035743A :
L
LEVEL1
14.32 UNIT DELAY
3180.67 UNIT AREA
仲西徳洋
根保光秀
ポセイドン・比嘉
1
設計した回路ブロックの構成説明
Degifm
MULT
D Q
AVG16
LOOPF
FMout
FMin
1/1024
COSROM
NCO
図 1: 回路ブロック
図 1 のように、FM レシーバ (degfm) は乗算機 (MLUT) とループフィルター (LOOPF) と NCO
とローパスフィルタ (AVG16) をつなげて回路を構成した。枠で囲まれている所は読み込んだ回路
を表している。また、信号の流れは矢印で表している。FM レシーバは FMin を受け取って FMout
を出力するような 1 入力 1 出力の回路に構成した。
2
設計した各回路ブロックの動作説明
ループフィルターからクロックサイクルごとに入力される信号のうち、最新の 16 個の平均値を
出力する。
2.1
NCO
入力のディジタル値を変化させることで、異なる周波数の正弦波形を出力する回路。入力された
2つの値を加算し、その値を下の加算器と FF で累積していく。累積値は¡17,0,u¿で与えられるの
で累積していった値が 1.0 を超えるとその部分は捨てられ 0.0 に戻ることになる。また、17 ビット
は細かいので、一周期を 1024 点に分割しその入力値より COSINE の値を ROM より取り出して
いる。
2.2
ループフィルター
移動平均回路よりも少ない回路規模でほぼ平均の値を計算するフィルター回路。ループフィル
ターは入力値に固定値 α(0.9375) を乗算したものを加算する回路になっている。したがって c(t) が
ループフィルターに入力された時のループフィルターの出力は下記の式で与えられる。α は1以下
の値なので、c(t) のこれまで平均のような演算になる。ただし、古いデータほど影響力は小さく
なる。
loopout = c(t) + α・c(t − 1) + α2・c(t − 2) +・
・
・
3
工夫した点
私たちグループは”速い回路を設計する”を目標に回路を合成した。図 1 を見て分かるように、処
理をしている回路は、component で読み込んで構成しているので、各回路の速度が最小になるよ
うに工夫すれば全体が速くなると考え, 各々の回路の工夫した点を下記に示す。
1
ループフィルタ 回路合成図を下記に示す。
QD
15/16
工夫した点は 15/16 した後、加算機に信号を送る
時に FF を間に入れた所である。FF を間に挟む
DQ
事でループフィルタの速度が減少した。
SOUT
SIN
図 2: ループフィルタのブロック図
ロウパスフィルタ 工夫した点を下記に示す。
ロウパスフィルタは移動平均で実現している、ここでは平均を求める加算に注目してみた。
工夫する前の回路では FF の値をすぐ SUM に入れているので速度が遅い、そこで、クロッ
クで同期を取り、ピラミッドのように加算して行く事で速度を減少させた、この回路の加算
部のイメージ図を下記に示す。
ピラミッド形加算機の利点は、16 の入力がある加
算の処理を 2 入力 1 出力の加算機だけで実現でき
るので速度が速くなる、また、フリップフロップ
で入力の同期を取っているので 1 クロックで加算
I
N
O
U
T
P
U
T
P
U
T
する数が変更前より少なくてすむので結果として
速度が減少する。移動平均の加算部分を変更した
場合下記のような結果が出た。
-
変更前
変更後
面積
2528
5049
速度
12.37
8.25
図 3: 加算部のイメージ図
上表のように、面積は 2 倍になっているが速度は
減少している。
NCO COSROM の値を 1024 から、512 に変更した場合、面積は大幅に減少したが速度は 0.5 秒
ほど遅くなった。今回のテーマは”速い回路”なので COSROM は 1024 に戻した。
4
クリティカルパスのスピード、論理合成後の回路規模
Total cell area
3180.67 UNIT AREA
data arrival time
14.32 UNIT DELAY
Clock CLK
18.36
2
5
VHDL コード
¶
FM レシーバの vhdl 記述 degifm.vhd
³
library IEEE;
use IEEE.STD LOGIC 1164.all;
use IEEE.STD LOGIC ARITH.all;
entity DEGIFM is port( CLK:in std logic;
RESET : in std logic;
FMin : in std logic vector(7 downto 0); – <8,0,t>
FMout : out std logic vector(11 downto 0) ); – <12,4,t>
end DEGIFM;
architecture RTL of DEGIFM is
–ループフィルターを読み込む
component LOOPF is
port(
CLK : in std logic;
RESET : in std logic;
SIN : in std logic vector(7 downto 0); – <8,0,t>
SOUT : out std logic vector(11 downto 0) ); – <12,4,t>
end component;
signal SIN : std logic vector(7 downto 0); – <8,0,t>
signal SOUT : std logic vector(11 downto 0); – <12,4,t>
–NCO を読み込む
component NCO is
port (
CLK : in std logic;
RESET : in std logic;
DELTA : in std logic vector(11 downto 0); – <12,-6,t>
OFFSET : in std logic vector(16 downto 0); – <17, 0,u>
COSOUT : out std logic vector(7 downto 0) ); – <8,0,t>
end component;
signal COSOUT : std logic vector(7 downto 0); – <8,0,t>
signal DELTA : std logic vector(11 downto 0); – <12, 0,u>
signal OFFSET : std logic vector(16 downto 0); – <17, 0,u>
–移動平均を読み込む
component AVG16 is
port(CLK : in std logic;
FMINPUT : in std logic vector(11 downto 0); –<12,4,t>
AVGOUT : out std logic vector(11 downto 0)); –<12,4,t>
end component;
signal FMINPUT : std logic vector(11 downto 0);
signal AVGOUT : std logic vector(11 downto 0);
component MULT is
port(in1 : in std logic vector(7 downto 0);
in2 : in std logic vector(7 downto 0);
outp : out std logic vector(7 downto 0));
end component;
signal in1 : std logic vector(7 downto 0);
signal in2 : std logic vector(7 downto 0);
signal outp : std logic vector(7 downto 0);
signal
signal
signal
signal
signal
lp : std logic vector(11 downto 0); – <12,4,t>
fmm : std logic vector(7 downto 0); – <8,0,t>
ncofm : std logic vector(7 downto 0); – <8,0,t>
seki : std logic vector(7 downto 0); – <8,0,t>
shou : std logic vector(11 downto 0); – <12,-6,t>
begin
–INPUT DFF
IN DFF:process(CLK, RESET) begin
if(RESET = ’1’) then
fmm <= ”00000000”;
elsif(CLK’event and CLK = ’1’) then
fmm<=FMin;
end if;
end process IN DFF;
–乗算
TIMES:process(fmm,COSOUT) begin
in1<=fmm;
in2<=COSOUT;
end process TIMES;
–ループフィルターの処理
LOOP1:process(outp) begin
SIN<=outp;
end process LOOP1;
–NCO の処理
NCO1:process (SOUT) begin
OFFSET<= ”00010000000000000”;
DELTA<=SOUT;
end process NCO1;
–移動平均の処理
AVG:process (SOUT) begin
FMINPUT<=SOUT;
end process AVG;
FMout<=AVGOUT;
–ユニット宣言集
U0:MULT port map (in1,in2,outp);
U1:LOOPF port map (CLK,RESET,SIN,SOUT);
U2:NCO port map (CLK,RESET,DELTA,OFFSET,COSOUT);
U3:AVG16 port map (CLK,FMINPUT,AVGOUT);
end RTL;
µ
´
3
¶
NCO の VHDL 記述:nco.vhd
³
library IEEE;
use IEEE.std logic 1164.all;
use IEEE.std logic arith.all;
entity NCO is
port (
CLK : in std logic;
RESET : in std logic;
DELTA : in std logic vector(11 downto 0); – <12,-6,t>
OFFSET : in std logic vector(16 downto 0); – <17, 0,u>
COSOUT : out std logic vector(7 downto 0) ); – <8,0,t>
end NCO;
architecture RTL of NCO is
component COSROM is
port (
DATA : out std logic vector(7 downto 0);
ADDR : in std logic vector(9 downto 0)
);
end component;
signal
signal
signal
signal
signal
sum : std logic vector(16 downto 0); – <17,0,u>
accm : std logic vector(16 downto 0); – <17,0,u>
accm d : std logic vector(16 downto 0); – <17,0,u>
addr : std logic vector(8 downto 0); – <9,0,u>
data : std logic vector(7 downto 0); – <8,0,t>
begin
– INPUT ADDER
INPUT SUM: process(OFFSET,DELTA)
variable var vext : std logic vector(16 downto 0); – <17,-1,t>
variable var tsum : std logic vector(16 downto 0); – <17,-1,t>
begin
var vext := DELTA(11) & DELTA(11)& DELTA(11) & DELTA(11) & DELTA(11) & DELTA;
var tsum := signed(OFFSET) + signed(var vext);
sum <= var tsum;
end process INPUT SUM;
– ACCUMULATOR
accm <= unsigned(sum) + unsigned(accm d);
ACCM DFF: process(CLK, RESET) begin
if(RESET = ’1’) then
accm d <= ”00000000000000000”;
elsif(CLK’event and CLK = ’1’) then
accm d <= accm;
end if;
end process ACCM DFF;
– COSINE ROM
addr <= accm(16 downto 7);
U1: COSROM port map (data, addr);
– OUTPUT FF
OUT FF: process(CLK) begin
if(CLK’event and CLK=’1’) then
COSOUT <= data;
end if;
end process OUT FF;
end RTL;
µ
¶
COSROM の VHDL 記述 : cosrom.vhd
´
³
library IEEE;
use IEEE.std logic 1164.all;
use IEEE.std logic arith.all;
entity COSROM is
port (
data : out std logic vector(7 downto 0);
addr : in std logic vector(9 downto 0));
end COSROM;
architecture RTL of COSROM is
begin
process (addr)
variable iaddr : integer;
type rom type is array(0 to 1024) of std logic vector(7 downto 0);
constant rom table : rom type := (
”01111111”,”01111111”,”01111111”,”01111111”,
”01111111”,”01111111”,”01111111”,”01111111”,
∼省略∼
”01111111”,”01111111”,”01111111”,”01111111”,
”01111111”,”01111111”,”01111111”,”01111111”);
begin
iaddr := conv integer(unsigned(addr));
data <= rom table(iaddr);
end process;
end RTL;
µ
´
4
¶
VHDL 記述 : mult.vhd
³
1 library IEEE;
2 use IEEE.STD LOGIC 1164.all;
3 use IEEE.STD LOGIC ARITH.all;
4
5 entity MULT is
6 port(CLK : in std logic;
7 in1 : in std logic vector(7 downto 0);
8 in2 : in std logic vector(7 downto 0);
9 outp : out std logic vector(7 downto 0);
10
11 end MULT;
12
13 architecture RTL of MULT is
14 –subtype JK is std logic vector(7 to 0);
15 –type F is array ( 0 to 15 ) of JK;
19 begin
20
21 – SIGNED CLIP ROUND MULTIPLIER
22 – in1 <8,0,t>
23 – in2 <8,0,t>
24 – outp <8,0,t>
25 MULT : process(in1,in2,CLK)
26 variable var outp : std logic vector(7 downto 0); – <8,0,t>
27 variable var tprod : std logic vector(15 downto 0); – <16,1,t> 28 variable var vtrun :
std logic vector(8 downto 0); – <9,1,t>
29 variable var rndbit : std logic; – <1,1,u>
30 variable var vext : std logic vector(9 downto 0); – <10,2,t>
31 variable var vext 1 : std logic vector(9 downto 0); – <10,2,t>
32 variable var tinc : std logic vector(9 downto 0); – <10,2,t>
33 variable var vrnd : std logic vector(9 downto 0); – <10,2,t>
34 variable var vovflo : std logic vector(7 downto 0); – <8,0,t>
35 begin
36 var tprod := signed(in1) * signed(in2);
37 var vtrun := var tprod(15 downto 7);
38 – ROUND
39 var rndbit := ’0’;
40 if (var tprod(6) = ’1’) then
41 var rndbit := ’1’;
42 end if;
43 var vext := var vtrun(8) & var vtrun;
44 var vext 1 := var vtrun(8) & var vtrun;
45 var tinc := signed(var vext 1) + ’1’;
46 if (var rndbit = ’1’) then
47 var vrnd := var tinc;
48 else
49 var vrnd := var vext;
50 end if;
51 – CLIP (IF OVERFLOW then take MAXVALUE)
52 – (IF UNDERFLOW then take MINVALUE)
53 var vovflo := var vrnd(7 downto 0);
54 if (var vrnd(9 downto 7) /= (var vrnd(9)&var vrnd(9)&var vrnd(9))) then
55 var vovflo := (7=>var vrnd(9),others=>(not var vrnd(9)));
56 end if;
78 – generate output
79 var outp := var vovflo;
80 outp <= var outp;
81 end process MULT;
97 end RTL;
µ
´
5
¶
ループフィルターの VHDL 記述 : loopf.vhd
³
library IEEE;
use IEEE.std logic 1164.all;
use IEEE.std logic arith.all;
entity LOOPF is
port (
CLK : in std logic;
RESET : in std logic;
SIN : in std logic vector(7 downto 0); – <8,0,t>
SOUT : out std logic vector(11 downto 0) ); – <12,4,t>
end LOOPF;
architecture RTL of LOOPF is
signal
signal
signal
signal
sum : std logic vector(11 downto 0); – <12,4,t>
dff : std logic vector(11 downto 0); – <12,4,t>
shift : std logic vector(11 downto 0); – <12,4,t>
sub : std logic vector(11 downto 0); – <12,4,t>
begin – ADDER FF をいれてスピード UP
process(CLK)begin
if(CLK’event and CLK=’1’)then
sum <= signed(sub)+signed(SIN(7)& SIN(7)& SIN(7)& SIN(7)& SIN);
end if;
end process;
– DFF
process(CLK, RESET) begin
if(RESET = ’1’) then
dff <= ”000000000000”;
elsif(CLK’event and CLK = ’1’) then
dff <= sum;
end if;
end process;
– 4 bit shifter
shift <= dff(11)& dff(11)& dff(11)& dff(11)& dff(11 downto 4);
– SUBTRACTER
process(CLK, RESET) begin
if(RESET=’1’) then
sub <= ”000000000000”;
elsif(CLK’event and CLK = ’1’) then
sub <= signed(dff) - signed(shift);
end if;
end process;
– OUTPUT
SOUT <= dff;
end RTL;
µ
´
6
¶
移動平均の VHDL 記述:avg16.vhd
³
library IEEE;
use IEEE.STD LOGIC 1164.all;
use IEEE.STD LOGIC ARITH.all;
entity AVG16 is
port(CLK : in std logic;
FMINPUT : in std logic vector(11 downto 0);
AVGOUT : out std logic vector(11 downto 0));
end AVG16;
architecture RTL of AVG16 is
signal FF1, FF2, FF3, FF4,FF5,FF6,FF7,FF8,FF9,FF10,FF11,FF12,FF13,FF14,FF15,FF16 :
std logic vector(11 downto 0);
signal SUM : std logic vector(15 downto 0);
signal S1,S2,S3,S4,S5,S6,S7,S8: std logic vector(12 downto 0);
signal S9,S10,S11,S12:std logic vector(13 downto 0);
signal S13,S14 :std logic vector(14 downto 0);
begin
– SHIFT REGISTER
process(CLK) begin
if (CLK’event and CLK = ’1’) then
FF1 <= FMINPUT;
FF2 <= FF1;
FF3 <= FF2;
FF4 <= FF3;
FF5 <= FF4;
FF6 <= FF5;
FF7 <= FF6;
FF8 <= FF7;
FF9 <= FF8;
FF10 <= FF9;
FF11 <= FF10;
FF12 <= FF11;
FF13 <= FF12;
FF14 <= FF13;
FF15 <= FF14;
FF16 <= FF15;
end if;
end process;
–ピラミッド型加算器でスピード UP
process (CLK) begin
if (CLK’event and CLK=’1’) then
S1 <= signed(FF1(11)& FF1)+signed(FF2(11)& FF2);
S2 <= signed(FF3(11)& FF3)+signed(FF4(11)& FF4);
S3 <= signed(FF5(11)& FF5)+signed(FF6(11)& FF6);
S4 <= signed(FF7(11)& FF7)+signed(FF8(11)& FF8);
S5 <= signed(FF9(11)& FF9)+signed(FF10(11)& FF10);
S6 <= signed(FF11(11)& FF11)+signed(FF12(11)& FF12);
S7 <= signed(FF13(11)& FF13)+signed(FF14(11)& FF14);
S8 <= signed(FF15(11)& FF15)+signed(FF16(11)& FF16);
S9 <= signed(S1(12)& S1)+signed(S2(12)& S2);
S10 <= signed(S3(12)& S3)+signed(S4(12)& S4);
S11 <= signed(S5(12)& S5)+signed(S6(12)& S6);
S12 <= signed(S7(12)& S7)+signed(S8(12)& S8);
S13 <= signed(S9(13)& S9)+signed(S10(13)& S10);
S14 <= signed(S11(13)& S11)+signed(S12(13)& S12);
SUM <= signed(S13(14)& S13)+signed(S14(14)& S14);
end if;
end process;
– DIVIDE BY 4 (SHIFT 2 bit), OUTPUT REGISTER
process(CLK) begin
if (CLK’event and CLK=’1’) then
AVGOUT <= SUM(15 downto 4);
end if;
end process;
end RTL;
µ
´
7
6
正常動作しているシミュレーション波形
図 4: 正常動作している波形
7
その他自由意見など
今回のこのデジタル FM レシーバーは、今まで授業で行ってきた事が利用できたのでどうにか
なったが、他の事で忙しかったため課題に取り組む時間が少なく、満足のいく結果が得られなかっ
た。しかし、合成を何度も繰り返すと面積・速度ともに減少して行った。今回のレポートで報告し
た値は合成を 3 回行ったものである。このやり方はすこしインチキくさいので、これからは一回の
合成で最速の回路にも挑戦してみたい。
8