guruguru123’s diary

かなり雑な作業日記です。

Papilio Pro基板上SDRAMの利用(5)

プログラムを組み終わり、コンパイルからbitファイル生成までエラーなく成功した。しかし、SDRAMからのデータ読み出しの出力を確認したところ読み出しがうまくいっていないことがわかった。プログラムを確認したところSDRAMの信号線を何本か接続し忘れていた。

 

前回配線ミスを修正して、論理合成が完了してFPGAに書き込んでも正しく動作しなかった。Errorは出ていないところを見るとErrorを抜けてWarningのほうにミスが出ているようだ。試作段階で、後から使う信号線等とりあえず宣言してあるものが多いので、これをつぶしていくのは大変そうだ。

 

プログラムを作りなおしたらまた更新する。

Papilio Pro基板上SDRAMの利用(4)

基本的なSDRAMの動作について勉強したが、いまいちアドレス指定の仕方がわからない。ざっくりとアドレス指定のブロック図を示すと以下のようになると思う。SDRAMはクロックに同期して動作するため、ロウ/カラム・アドレスは同一の信号線を用いる。図では、バンクを指定してからロウ・アドレスを指定となっているが、データシートを見ると、実際に指定する際には同時に行うようだ。

f:id:guruguru123:20160616232946p:plain

起動直後は、このループに入る前にモードレジスタを設定する必要があり、アドレスの信号線を用いて行う。

自分で作成するものは、まずシングルライトでバースト長1のものを作成する。とりあえず1つのデータを読み書きできるようにする。

最終的な目標としては、AD9851に出力する40bitデータをSDRAMに蓄えておき、順次読み出してAD9851の出力を高速に切り替えられるようにしたい。実際には8bitは固定で32bitデータのやり取りになるだろう。

Papilio Pro基板上SDRAMの利用(3)

前回rとnが何だかわからないと書いたが、用途はだいたいわかった。このプログラムは3つのprocess文から成り立っていて、rとnが出てくるのは以下2つだ。

1.process (r, rstate, address, req_read, rdata_write, req_write, addr_row, addr_bank, addr_col, data_in, captured, data_mask)と2.process (clock_100, n)

1のほうでは n <= r と代入文があり現状をコピーしている。2のほうでは、リセット信号がなければr <= n の代入となっている。

rとnはクロックごとに入れ替えが行われている。process文の中身をざっと見たところrが記録用で、nが変更用といったところか。それぞれのprocess文の中身はまた後で見ていく。

少しずつ自分でもsdramコントローラを作成していく。まずは電源ONからモードレジスタ設定、アクティブまで行えるものを作成したい。

 

時間があったのでグラフィックボードの取り付けを行った。

Papilio Pro基板上SDRAMの利用(2)

前回はentuty内部を見たので、今回からarchitecture内部を見ていく。

レコードタイプの定義
 type reg is record
  address : std_logic_vector(ADDRESS_BITS-1 downto 0);
  bank : std_logic_vector( 1 downto 0);
  init_counter : std_logic_vector(14 downto 0);
  rf_counter : integer;
  rf_pending : std_logic;
  rd_pending : std_logic;
  wr_pending : std_logic;
  act_row : std_logic_vector(ADDRESS_BITS-1 downto 0);
  act_ba : std_logic_vector(1 downto 0);
  data_out_low : std_logic_vector(15 downto 0);
  req_addr_q : std_logic_vector(HIGH_BIT downto 2);
  req_data_write: std_logic_vector(31 downto 0);
  req_mask : std_logic_vector(3 downto 0);
  data_out_valid: std_logic;
  dq_masks : std_logic_vector(1 downto 0);
  tristate : std_logic;
 end record;
record命令を用いて関連したデータをひとつにまとめている。そしてすぐ下の
 signal r : reg;
 signal n : reg;
で、このデータタイプを用いた信号宣言をしている。このrとnが何かの頭文字なのか、何を指しているのかはわからない。ADDRESS_BITSやHIGH_BITはgenericで定義したものが使われる。

その下の
 signal rstate : std_logic_vector(8 downto 0);
 signal nstate : std_logic_vector(8 downto 0);
 signal rdata_write : std_logic_vector(15 downto 0);
 signal ndata_write : std_logic_vector(15 downto 0);
は上の二つが状態を表し、下の二つが書き込み信号。

Micron社製64MbitのSDRAM,MT48LC4M16A2のデータシートがあったので、これも読んでいる。

Papilio Pro基板上SDRAMの利用(1)

ad9851の出力の周波数・位相を高速に切り替える(μs単位が目標)ためにあらかじめPapilio Pro基板上のSDRAMにad9851へ書き込む40bitデータと時間のデータを与えておく。それを順次読み出して40bitデータをad9851へ書き込みをできるようにする。

そのためにはまずSDRAMをコントローラで

http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller

https://github.com/alvieboy/ZPUino-HDL/blob/dcache/zpu/hdl/zpuino/boards/papilio-pro/S6LX9/sdram_hamster.vhd

以上のサイトを参考にしながら読み書きできるようにしていく。

Papiio Pro上のSDRAMはMicron社製64MbitのSDRAM,MT48LC4M16A2。16Mbit→2^26であるので26個のアドレスが必要になる。しかし、26桁のアドレス指定用信号を用意するのでは長すぎる。そのためロウアドレス(RAS)と絡むアドレス(CAS)、バンクを用いる。SDRAMはコマンドによる制御を必要とする。

まずはentity内部から

generic (
 HIGH_BIT: integer := 24;
 MHZ: integer := 96;
 REFRESH_CYCLES: integer := 4096;
 ADDRESS_BITS: integer := 12
 );
ここでは、後に変更し得る値を設定している。

以下入出力ポート

 clock_100: in std_logic;
 clock_100_delayed_3ns: in std_logic;
 rst: in std_logic;
clock_100とclock_100_delayed_3nsが何を指しているのかわからなかった。rstはリセット信号。

以下が SDRAM用信号
 DRAM_ADDR : OUT STD_LOGIC_VECTOR (ADDRESS_BITS-1 downto 0);
 DRAM_BA : OUT STD_LOGIC_VECTOR (1 downto 0);
 DRAM_CAS_N : OUT STD_LOGIC;
 DRAM_CKE : OUT STD_LOGIC;
 DRAM_CLK : OUT STD_LOGIC;
 DRAM_CS_N : OUT STD_LOGIC;
 DRAM_DQ : INOUT STD_LOGIC_VECTOR(15 downto 0);
 DRAM_DQM : OUT STD_LOGIC_VECTOR(1 downto 0);
 DRAM_RAS_N : OUT STD_LOGIC;
 DRAM_WE_N : OUT STD_LOGIC;
各ポート説明
DRAM_ADDR:アドレス信号。ロウアドレスとカラムアドレスを入力する。
SDRAM_BA:2bitのバンク。                          
DRAM_CKE:クロックイネーブル。                      
DRAM_CLK:クロック信号。                          
DRAM_CD_N:チップセレクト信号。                      
DRAM_WE_N:書き込みイネーブル信号。                   
DRAM_DQ:入出力データ信号。                        
DRAM_RAS_N:この信号がハイの間、アドレス信号にロウアドレスが入力される。 
DRAM_CAS_N:この信号がハイの間、アドレス信号にカラムアドレスが入力される。
DRAM_DQM:データマスクイネーブル

以下がアクセス用信号
 address : IN STD_LOGIC_VECTOR (HIGH_BIT downto 2);
 req_read : IN STD_LOGIC;
 req_write : IN STD_LOGIC;
 data_out : OUT STD_LOGIC_VECTOR (31 downto 0);
 data_out_valid : OUT STD_LOGIC;
 data_in : IN STD_LOGIC_VECTOR (31 downto 0);
 data_mask : IN STD_LOGIC_VECTOR (3 downto 0);
各ポート説明
address:アドレス入力であり、ロウアドレスとカラムアドレスを入力する。
req_read:読み出しリクエスト信号。                     req_write:書き込みリクエスト信号。                     data_out:出力信号。                              data_in:入力信号。
data_out_valid:出力有効判定
data_mask : データマスク

わからなかったポートについては後で調べる。データマスクについてよくわかっていないので、別途学習したい。引き続きこのプログラムの構成を見ていく。

FPGAでArduino(7)

DDS-LSIであるad9851を駆動し、周波数・位相を高速で切り替えるためにXilinx社製のFPGA:Spaltan-6を搭載した開発用基板Papilio Proを用いて40bitのデータを書き込む。これにはZAP IDEから周波数と位相の数値データの入力し、FPGAプログラムで40bitデータを生成、ad9851をドライブする。

 

FPGAArduinoとあるが、これはFPGA上にプロセッサZPUino(Xilinx社の32bitプロセッサZPUベースのSoC)を構成し、Arduinoと同じ手順でスケッチ(Arduinoプログラム)を作成し書き込みをできるようにしたものである。ZPUinoのソースコードに回路32bit周波数データ生成回路、8bitデータ生成回路、40bit書き込み回路を追加していく。現状では、単に40bitデータの生成・書き込みが可能なプログラムができている。以下に作成したプログラムを示す。ソースコードすべてを載せると長くなってしまうので、変更部分のみ。

 

・ZPUinoトップ回路追加・変更部
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
library work;
use work.zpupkg.all;
use work.zpuinopkg.all;
use work.zpuino_config.all;
use work.zpu_config.all;
use work.pad.all;
use work.wishbonepkg.all;

entity papilio_pro_top is
~省略~
-- Papilio Note: Place your signal statements here. #Signal
signal data32: std_logic_vector(31 downto 0);
signal phasedata: std_logic_vector(7 downto 0);
signal led32:std_logic_vector(31 downto 0);
signal count_in : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal count_in3 : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal my_ad9851data : std_logic := '0';
signal count_in2 : std_logic_vector(23 downto 0) := "000000000000000000000000";
signal my_ad9851fqud : std_logic;
signal my_ad9851reset : std_logic;
signal freqcheck : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal phasecheck : std_logic_vector(7 downto 0) := "00000000";
signal datacheck : std_logic;
signal my_clock : std_logic;
signal x : integer range 0 to 15 := 0;
signal count_in4 : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal clkplus : std_logic;

component freqset is
port (
clk : in std_logic;
resetb : in std_logic;
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_dat_o: out std_logic_vector(31 downto 0);
wb_dat_i: in std_logic_vector(31 downto 0);
wb_adr_i: in std_logic_vector(24 downto 0);
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_stb_i: in std_logic;
wb_ack_o: out std_logic;
wb_inta_o:out std_logic;
data32:out std_logic_vector(31 downto 0)
);
end component freqset ;

component phaseset is
port (
clk : in std_logic;
resetb : in std_logic;
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_dat_o: out std_logic_vector(31 downto 0);
wb_dat_i: in std_logic_vector(31 downto 0);
wb_adr_i: in std_logic_vector(24 downto 0);
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_stb_i: in std_logic;
wb_ack_o: out std_logic;
wb_inta_o:out std_logic;
phasedata:out std_logic_vector(7 downto 0)
);
end component phaseset ;
~省略~
pin41: IOPAD port map(I => gpio_o(41),O => gpio_i(41),T => gpio_t(41),C => sysclk,PAD => WING_C(9) );
pin42: IOPAD port map(I => gpio_o(42),O => gpio_i(42),T => gpio_t(42),C => sysclk,PAD => WING_C(10) );
--pin43: IOPAD port map(I => gpio_o(43),O => gpio_i(43),T => gpio_t(43),C => sysclk,PAD => WING_C(11) );
--pin44: IOPAD port map(I => gpio_o(44),O => gpio_i(44),T => gpio_t(44),C => sysclk,PAD => WING_C(12) );
--pin45: IOPAD port map(I => gpio_o(45),O => gpio_i(45),T => gpio_t(45),C => sysclk,PAD => WING_C(13) );
--pin46: IOPAD port map(I => gpio_o(46),O => gpio_i(46),T => gpio_t(46),C => sysclk,PAD => WING_C(14) );
--pin47: IOPAD port map(I => gpio_o(47),O => gpio_i(47),T => gpio_t(47),C => sysclk,PAD => WING_C(15) );
//ピン43から47は後に記述するためコメントアウト
~省略~

--
-- IO SLOT 13
--

slot13: freqset
port map (
clk => sysclk,
resetb => sysrst,
data32 => data32,
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_dat_o => slot_read(13),
wb_dat_i => slot_write(13),
wb_adr_i => slot_address(13),
wb_we_i => slot_we(13),
wb_cyc_i => slot_cyc(13),
wb_stb_i => slot_stb(13),
wb_ack_o => slot_ack(13),
wb_inta_o => slot_interrupt(13)
);

process (sysclk , sysrst) begin
if rising_edge (sysclk) then
if(sysrst = '1')then
count_in2 <= (23 downto 0 => '0');
else
count_in2 <= count_in2 + '1';
end if;
end if;
end process;

process (count_in2(20), sysrst) begin
if falling_edge(count_in2(20)) then
if(sysrst = '1' or count_in3(5 downto 0) = "000000"
or count_in3(5 downto 0) = "000001" or count_in3(5 downto 0) = "000010"
or count_in3(5 downto 0) = "000011" or count_in3(5 downto 0) = "000100"
or count_in3(5 downto 0) = "000101"or count_in3(5 downto 0) = "000110"
or count_in3(5 downto 0) = "110000" or count_in3(5 downto 0) = "110001"
or count_in3(5 downto 0) = "110010" )then
count_in <= (31 downto 0 => '0');
else
count_in <= count_in + '1';
end if;
end if;
end process;

process (count_in2(20), sysrst) begin
if rising_edge (count_in2(20)) then
if(sysrst = '1')then
count_in4 <= (31 downto 0 => '0');
else
count_in4 <= count_in4 + '1';
end if;
end if;
end process;

process (count_in4(0), sysrst) begin
if rising_edge (count_in4(0)) then
if(sysrst = '1' or count_in3(5 downto 0) = "110010")then
count_in3 (5 downto 0) <= "110010";--<= (31 downto 0 => '0');--
else--if(count_in(0) = '1')then
count_in3 <= count_in3 + '1';
--else
--count_in3 <= count_in3;
end if;
end if;
end process;

//ここからリセット信号と40bitデータをAD9851の各ピンに相当するレジスタへ代入
process (sysclk) begin
if rising_edge(sysclk)then
case count_in3(5 downto 0) is
when "000001" => my_ad9851reset <= '1';
when "000010" => my_ad9851reset <= '0';
when "000011" => clkplus <= '1';
when "000100" => clkplus <= '0';
when "000101" => my_ad9851fqud <= '1';
when "000110" => my_ad9851fqud <= '0';
when "000111" => my_ad9851data <= data32(31);
when "001000" => my_ad9851data <= data32(30);
when "001001" => my_ad9851data <= data32(29);
when "001010" => my_ad9851data <= data32(28);
when "001011" => my_ad9851data <= data32(27);
when "001100" => my_ad9851data <= data32(26);
when "001101" => my_ad9851data <= data32(25);
when "001110" => my_ad9851data <= data32(24);
when "001111" => my_ad9851data <= data32(23);
when "010000" => my_ad9851data <= data32(22);
when "010001" => my_ad9851data <= data32(21);
when "010010" => my_ad9851data <= data32(20);
when "010011" => my_ad9851data <= data32(21);
when "010100" => my_ad9851data <= data32(19);
when "010101" => my_ad9851data <= data32(18);
when "010110" => my_ad9851data <= data32(17);
when "010111" => my_ad9851data <= data32(16);
when "011000" => my_ad9851data <= data32(15);
when "011001" => my_ad9851data <= data32(14);
when "011010" => my_ad9851data <= data32(13);
when "011011" => my_ad9851data <= data32(12);
when "011100" => my_ad9851data <= data32(11);
when "011101" => my_ad9851data <= data32(10);
when "011110" => my_ad9851data <= data32(9);
when "011111" => my_ad9851data <= data32(8);
when "100000" => my_ad9851data <= data32(7);
when "100001" => my_ad9851data <= data32(6);
when "100010" => my_ad9851data <= data32(5);
when "100011" => my_ad9851data <= data32(4);
when "100100" => my_ad9851data <= data32(3);
when "100101" => my_ad9851data <= data32(2);
when "100110" => my_ad9851data <= data32(1);
when "100111" => my_ad9851data <= data32(0);
when "101000" => my_ad9851data <= phasedata(0);
when "101001" => my_ad9851data <= phasedata(1);
when "101010" => my_ad9851data <= phasedata(2);
when "101011" => my_ad9851data <= phasedata(3);
when "101100" => my_ad9851data <= phasedata(4);
when "101101" => my_ad9851data <= phasedata(5);
when "101110" => my_ad9851data <= phasedata(6);
when "101111" => my_ad9851data <= phasedata(7);
when "110000" => my_ad9851fqud <= '1';
when "110001" => my_ad9851fqud <= '0';
when others => my_ad9851data <= '0';
end case;
end if;
end process;

//最終的にはレジスタに蓄えていたデータを各ピンへ出力。
WING_C(12) <= my_ad9851data;
WING_C(13) <= count_in(0) or clkplus;
WING_C(14) <= my_ad9851fqud;
WING_C(15) <= my_ad9851reset;

--
-- IO SLOT 14
--

slot14: phaseset
port map (
clk => sysclk,
resetb => sysrst,
phasedata => phasedata,
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_dat_o => slot_read(14),
wb_dat_i => slot_write(14),
wb_adr_i => slot_address(14),
wb_we_i => slot_we(14),
wb_cyc_i => slot_cyc(14),
wb_stb_i => slot_stb(14),
wb_ack_o => slot_ack(14),
wb_inta_o => slot_interrupt(14)
);
~省略~
end behave;
・slot13追加回路
`timescale 1ns / 1ps

module freqset(
input clk,
input resetb,
//wishboneバス信号
input wb_clk_i,
input wb_rst_i,
output [31:0] wb_dat_o,
input [31:0] wb_dat_i,
input [24:0] wb_adr_i,
input wb_we_i,
input wb_cyc_i,
input wb_stb_i,
output wb_ack_o,
output wb_inta_o,
//AD9851信号
output [31:0] data32
);

reg wb_ack_o_ff;
reg [31:0] user_data_o_ff;
reg [31:0] user_data_i_ff;
reg [31:0] data_o;
reg [31:0] freqbit;
reg [31:0] freqdata=0;
reg [31:0] freqif;
reg outdata;
reg check;
integer i,j,k;

assign wb_ack_o = wb_ack_o_ff;
assign wb_inta_o = 1'b0;
assign wb_dat_o = data_o;

always @(posedge wb_clk_i)
begin
if(wb_cyc_i == 1'b1 && wb_stb_i == 1'b1 && wb_ack_o == 1'b0)
wb_ack_o_ff <= 1'b1;
else
wb_ack_o_ff <= 1'b0;
end

always begin
begin
case(wb_adr_i[5:2])
4'b0000:data_o = freqbit;
4'b0001:data_o = user_data_i_ff;
default:data_o = 1'b0;
endcase
end
end

always @(posedge wb_clk_i)
begin
if(wb_cyc_i == 1'b1 && wb_stb_i == 1'b1 && wb_we_i == 1'b1)
case(wb_adr_i[5:2])
4'b0000:user_data_o_ff = wb_dat_i;
default:user_data_o_ff = user_data_o_ff;
endcase
end

//32bitデータ生成
always @(posedge wb_clk_i)
begin:label1
freqdata = user_data_o_ff;
for(i=31; i>=0; i=i-1)begin
freqif = freqdata%2;
freqdata = freqdata/2;
if(freqif == 32'd1)
freqbit[i] = 1'b1;
else if(freqif == 32'd0)
freqbit[i] = 1'b0;
else
freqbit[i] = 1'b0;
end
end

assign data32 = freqbit;

endmodule

・slot14追加回路
`timescale 1ns / 1ps

module phaseset(
input clk,
input resetb,
//wishboneバス信号
input wb_clk_i,
input wb_rst_i,
output [31:0] wb_dat_o,
input [31:0] wb_dat_i,
input [24:0] wb_adr_i,
input wb_we_i,
input wb_cyc_i,
input wb_stb_i,
output wb_ack_o,
output wb_inta_o,
//ad9851信号
output [7:0] phasedata
);

reg wb_ack_o_ff;
reg [31:0]user_data_o_ff;
reg [31:0]user_data_i_ff;
reg [31:0]data_o;
reg [7:0] my_phasedata;
reg [31:0]phaseif;
reg [32:0]datacheck;
integer i,j,k;

assign wb_ack_o = wb_ack_o_ff;
assign wb_inta_o = 1'b0;
assign wb_dat_o = data_o;

always @(posedge wb_clk_i)
begin
if(wb_cyc_i == 1'b1 && wb_stb_i == 1'b1 && wb_ack_o == 1'b0)
wb_ack_o_ff <= 1'b1;
else
wb_ack_o_ff <= 1'b0;
end

always begin
begin
case(wb_adr_i[5:2])
4'b0000:data_o = my_phasedata;
4'b0001:data_o = user_data_i_ff;
default:data_o = 1'b0;
endcase
end
end

always @(posedge wb_clk_i)
begin
if(wb_cyc_i == 1'b1 && wb_stb_i == 1'b1 && wb_we_i == 1'b1)
case(wb_adr_i[5:2])
4'b0000:user_data_o_ff = wb_dat_i;
default:user_data_o_ff = user_data_o_ff;
endcase
end

//8bitデータ生成
always @(posedge wb_clk_i)
begin:label1
datacheck = user_data_o_ff;
my_phasedata[0]=1'b1;
my_phasedata[1]=1'b0;
my_phasedata[2]=1'b0;
for(i=3; i<8; i=i+1)begin
phaseif = datacheck%2;
datacheck = datacheck/2;
if(phaseif == 32'd1)
my_phasedata[i] = 1'b1;
else if(phaseif == 32'd0)
my_phasedata[i] = 1'b0;
else
my_phasedata[i] = 1'b0;
end
end

assign phasedata = my_phasedata;

endmodule

A5-3 ZAP IDE作成プログラム
ソフトウェアArduinoにおけるAD9851の駆動の際に作成したスケッチを以下に示す。
//スロット13のアドレス定義
#define UREGBase IO_SLOT(13)
#define UREG_OUT REGISTER(UREGBase,0);
#define UREG_IN REGISTER(UREGBase,1);

//スロット14のアドレス定義
#define UREGBase2 IO_SLOT(14)
#define UREG_OUT2 REGISTER(UREGBase2,0);
#define UREG_IN2 REGISTER(UREGBase2,1);

void setup(){
Serial.begin(9600);
}

void loop(){
int data;
int data2;
int freqdata;
int outputfreq;
int outputphase;
int x;
int y;

 //レジスタ用ポインタ
volatile unsigned int *ureg_out = &UREG_OUT;
volatile unsigned int *ureg_in = &UREG_IN;

volatile unsigned int *ureg_out2 = &UREG_OUT2;
volatile unsigned int *ureg_in2 = &UREG_IN2;

data=1;
data2=1;
//出力周波数、位相を入力
outputfreq=10000000;
outputphase=0;

while(1){
x=180000000/outputfreq;
freqdata=4294967295/x;
y = outputphase/11.25;
*ureg_out = freqdata;
*ureg_out2 = y;

data=*ureg_in;
data2=*ureg_in2;
Serial.println(data,BIN);
delay(100);
}
}

FPGAでArduino(6)

なんとなくコツがつかめてきたので、本題のAD9851へ40bitのデータを書き込むためのプログラムを作成していきたい。まずは、40biのデータをどうやって作成するかだが、これは、ZAPIDEで発振したい周波数、位相を指定し、それを40bitデータへ計算させるためSLOT13に転送する、と考えた。しかし、今回用いるWISHBONEバスは上限32bitまでしか転送できないので、周波数設定の32bitとその他設定の8bitの二回に分けることにした。

今回は周波数設定の32bitデータ作成プログラムを作った。すんなりいくと思いきや、ハードウェア記述言語特有のエラーが出てしまい、思ったように進まなかった。