實驗目的:我們都知道利用verilog編程,仿真和調(diào)試占據(jù)整個開發(fā)的很大一部分時間。有的時候臨時想到一個可修改的參數(shù),就要重新綜合,消耗很多時間。本文利用uart對FPGA進行寄存器的讀寫,一方面極大方便了自我調(diào)試,另一方面預先設(shè)置寄存器,免去了反復綜合的麻煩。為后續(xù)的調(diào)試、測試提供鋪墊。
實驗原理:例程中有的串口的收發(fā)程序,且已經(jīng)有串口硬件,但只起到驗證作用,本次實驗利用開源的串口驅(qū)動代碼,作者是John Clayton,基于“Wishbone system controller”方式設(shè)計,但是串口收發(fā)的原理是互通的,源代碼在一些細節(jié)及應用的地方投入了很多的思考,方便我們實際應用。
簡要例化代碼:
// This block is the rs232 user interface for debugging, programming etc.
rs232_syscon #(
2, //Number of Hex digits for addresses.
4, //Number of Hex digits for data.
2, //Number of Hex digits for quantity.
12, //Characters in the input buffer,as few as possible
6, //Bits in the buffer pointer
255, //Clocks before watchdog timer expires
8, //Bits in watchdog timer
8, //Number of data fields displayed per line
3, //Number of bits in the fields counter
2 //Number of bits in the digits counter
)
u_rs232_syscon
( // instance name
.clk_i (rs232_clk),
.reset_i (reset_finish),//rs232 port not reseted by reset_finish
.master_bg_i (master_br),
.ack_i (rs232_stb),
.err_i (1'b0),
.master_adr_i (8'h0),
.master_stb_i (1'b0),
.master_we_i (1'b0),
.rs232_rxd_i (rs232_rxd),
.dat_i (rs232_dat_i),
.dat_o (rs232_dat_o),
.rst_o (rs232_rst),
.master_br_o (master_br),
.stb_o (rs232_stb),
.cyc_o (),
.adr_o (rs232_adr),
.we_o (rs232_we),
.rs232_txd_o (rs232_txd_o)
);
// A transmitter, which asserts load_request at the end of the currently
// transmitted word. The tx_clk must be a "clock enable" (narrow positive
// pulse) which occurs at 16x the desired transmit rate. If load_request
// is connected directly to load, the unit will transmit continuously.
rs232tx #(
`START_BITS, // start_bits
`DATA_BITS, // data_bits
`STOP_BITS, // stop_bits (add intercharacter delay...)
`CLOCK_FACTOR // clock_factor
)
rs232_tx_block // instance name
(
.clk(clk_i),
// .tx_clk(serial_clk),
.reset(reset_i),
.load(rs232_tx_load),
.data(rs232_tx_char),
.load_request(rs232_tx_load_request),
.txd(rs232_txd_o)
);
// A receiver, which asserts "word_ready" to indicate a received word.
// Asserting "read_word" will cause "word_ready" to go low again if it was high.
// The character is held in the output register, during the time the next
// character is coming in.
rs232rx #(
`START_BITS, // start_bits
`DATA_BITS, // data_bits
`STOP_BITS, // stop_bits
`CLOCK_FACTOR // clock_factor
)
rs232_rx_block // instance name
(
.clk(clk_i),
// .rx_clk(serial_clk),
.reset(reset_i || (| rs232_rx_error)),
.rxd(rs232_rxd_i),
.read(rs232_tx_load),
.data(rs232_rx_char),
.data_ready(rs232_rx_data_ready),
.error_over_run(rs232_rx_error[0]),
.error_under_run(rs232_rx_error[1]),
.error_all_low(rs232_rx_error[2])
);
//寄存器初始值
always @ (posedge clk_54mhz or negedge pll_lock)
if (~pll_lock)begin
reg0 <= {16'h1234};
reg1 <= {16'h5678};
reg2 <= {16'haabb};
reg3 <= {16'hccdd};
reg4 <= {16'habcd};
reg5 <= {16'hfedc};
end
else
begin
if(sp_we & sp_addr == 8'h00 )begin
reg0 <= sp_wdata;
end
else if (sp_we & sp_addr == 8'h01 )begin
reg1 <= sp_wdata;
end
else if (sp_we & sp_addr == 8'h02 )begin
reg2 <= sp_wdata;
end
else if (sp_we & sp_addr == 8'h03 )begin
reg3 <= sp_wdata;
end
else if (sp_we & sp_addr == 8'h04 )begin
reg4 <= sp_wdata;
end
else if (sp_we & sp_addr == 8'h05 )begin
reg5 <= sp_wdata;
end
end
實驗現(xiàn)象:可用串口調(diào)試助手進行寄存器的讀寫00~9F寄存器的讀寫
說明:r 0 a0表示從0地址寄存器讀a0個寄存器位置;w 1 7599表示寫地址1的寄存器的內(nèi)容是7599。如圖所示,初始值編號1的寄存器內(nèi)容是5678,進行寫w 1 7599之后內(nèi)容更新為7599。