(原创)基于or1200最小sopc系统搭建(三)--串口
接上一篇(原创)基于or1200最小sopc系统搭建(二)--QuartuII工程及DE2平台下载现再为构建的or1200最小系统添加上串口。先进行仿真,再在DE2上验证,在hyperterminal上显示hello world!
从opencores网站上下载uart16550_latest.tar.gz,在or1200_sopc目录下新建uart16550目录,将uart16550的源码在解压到这个目录。修改or1200_sys.v文件。修改后文件如下:
module or1200_sys(
input clk_i,
input rst_n,
// buttons
input [15:0] SW,
// uart interface
input uart_rxd,
output uart_txd,
// segments
output [31:0] LEDR
);
wire rst = ~rst_n;
// **************************************************
// Wires from OR1200 Inst Master to Conmax m0
// **************************************************
wire wire_iwb_ack_i;
wire wire_iwb_cyc_o;
wire wire_iwb_stb_o;
wire [31:0] wire_iwb_data_i;
wire [31:0] wire_iwb_data_o;
wire [31:0] wire_iwb_addr_o;
wire [3:0] wire_iwb_sel_o;
wire wire_iwb_we_o;
wire wire_iwb_err_i;
wire wire_iwb_rty_i;
// **************************************************
// Wires from OR1200 Data Master to Conmax m1
// **************************************************
wire wire_dwb_ack_i;
wire wire_dwb_cyc_o;
wire wire_dwb_stb_o;
wire [31:0] wire_dwb_data_i;
wire [31:0] wire_dwb_data_o;
wire [31:0] wire_dwb_addr_o;
wire [3:0] wire_dwb_sel_o;
wire wire_dwb_we_o;
wire wire_dwb_err_i;
wire wire_dwb_rty_i;
// **************************************************
// Wires from Conmax s0 to onchip_ram0
// **************************************************
wire wire_ram0_ack_o;
wire wire_ram0_cyc_i;
wire wire_ram0_stb_i;
wire [31:0] wire_ram0_data_i;
wire [31:0] wire_ram0_data_o;
wire [31:0] wire_ram0_addr_i;
wire [3:0] wire_ram0_sel_i;
wire wire_ram0_we_i;
// **************************************************
// Wires from Conmax s1 to GPIO
// **************************************************
wire wire_gpio_ack_o;
wire wire_gpio_cyc_i;
wire wire_gpio_stb_i;
wire [31:0] wire_gpio_data_i;
wire [31:0] wire_gpio_data_o;
wire [31:0] wire_gpio_addr_i;
wire [3:0] wire_gpio_sel_i;
wire wire_gpio_we_i;
wire wire_gpio_err_o;
wire wire_gpio_interrupt;
// **************************************************
// Wires from Conmax s2 to uart16550
// **************************************************
wire wire_uart_ack_o;
wire wire_uart_cyc_i;
wire wire_uart_stb_i;
wire [31:0] wire_uart_data_i;
wire [31:0] wire_uart_data_o;
wire [31:0] wire_uart_addr_i;
wire [3:0] wire_uart_sel_i;
wire wire_uart_we_i;
wire wire_uart_interrupt;
or1200_top u_or1200(
// System
.clk_i(clk_i),
.rst_i(rst),
.pic_ints_i({18'b0,wire_uart_interrupt,wire_gpio_interrupt}),
.clmode_i(2'b00),
// Instruction WISHBONE INTERFACE
.iwb_clk_i(clk_i),
.iwb_rst_i(rst),
.iwb_ack_i(wire_iwb_ack_i),
.iwb_err_i(wire_iwb_err_i),
.iwb_rty_i(wire_iwb_rty_i),
.iwb_dat_i(wire_iwb_data_i),
.iwb_cyc_o(wire_iwb_cyc_o),
.iwb_adr_o(wire_iwb_addr_o),
.iwb_stb_o(wire_iwb_stb_o),
.iwb_we_o(wire_iwb_we_o),
.iwb_sel_o(wire_iwb_sel_o),
.iwb_dat_o(wire_iwb_data_o),
`ifdef OR1200_WB_CAB
.iwb_cab_o(),
`endif
//`ifdef OR1200_WB_B3
// iwb_cti_o(),
// iwb_bte_o(),
//`endif
// Data WISHBONE INTERFACE
.dwb_clk_i(clk_i),
.dwb_rst_i(rst),
.dwb_ack_i(wire_dwb_ack_i),
.dwb_err_i(wire_dwb_err_i),
.dwb_rty_i(wire_dwb_rty_i),
.dwb_dat_i(wire_dwb_data_i),
.dwb_cyc_o(wire_dwb_cyc_o),
.dwb_adr_o(wire_dwb_addr_o),
.dwb_stb_o(wire_dwb_stb_o),
.dwb_we_o(wire_dwb_we_o),
.dwb_sel_o(wire_dwb_sel_o),
.dwb_dat_o(wire_dwb_data_o),
`ifdef OR1200_WB_CAB
.dwb_cab_o(),
`endif
//`ifdef OR1200_WB_B3
// dwb_cti_o(),
// dwb_bte_o(),
//`endif
// External Debug Interface
.dbg_stall_i(1'b0),
.dbg_ewt_i(1'b0),
.dbg_lss_o(),
.dbg_is_o(),
.dbg_wp_o(),
.dbg_bp_o(),
.dbg_stb_i(1'b0),
.dbg_we_i(1'b0),
.dbg_adr_i(0),
.dbg_dat_i(0),
.dbg_dat_o(),
.dbg_ack_o(),
//`ifdef OR1200_BIST
// // RAM BIST
// mbist_si_i(),
// mbist_so_o(),
// mbist_ctrl_i(),
//`endif
// Power Management
.pm_cpustall_i(0),
.pm_clksd_o(),
.pm_dc_gate_o(),
.pm_ic_gate_o(),
.pm_dmmu_gate_o(),
.pm_immu_gate_o(),
.pm_tt_gate_o(),
.pm_cpu_gate_o(),
.pm_wakeup_o(),
.pm_lvolt_o()
);
wb_conmax_top u_wb(
.clk_i(clk_i),
.rst_i(rst),
// Master 0 Interface
.m0_data_i(wire_iwb_data_o),
.m0_data_o(wire_iwb_data_i),
.m0_addr_i(wire_iwb_addr_o),
.m0_sel_i(wire_iwb_sel_o),
.m0_we_i(wire_iwb_we_o),
.m0_cyc_i(wire_iwb_cyc_o),
.m0_stb_i(wire_iwb_stb_o),
.m0_ack_o(wire_iwb_ack_i),
.m0_err_o(wire_iwb_err_i),
.m0_rty_o(wire_iwb_rty_i),
// .m0_cab_i(),
// Master 1 Interface
.m1_data_i(wire_dwb_data_o),
.m1_data_o(wire_dwb_data_i),
.m1_addr_i(wire_dwb_addr_o),
.m1_sel_i(wire_dwb_sel_o),
.m1_we_i(wire_dwb_we_o),
.m1_cyc_i(wire_dwb_cyc_o),
.m1_stb_i(wire_dwb_stb_o),
.m1_ack_o(wire_dwb_ack_i),
.m1_err_o(wire_dwb_err_i),
.m1_rty_o(wire_dwb_rty_i),
// .m0_cab_i(),
// Slave 0 Interface
.s0_data_i(wire_ram0_data_o),
.s0_data_o(wire_ram0_data_i),
.s0_addr_o(wire_ram0_addr_i),
.s0_sel_o(wire_ram0_sel_i),
.s0_we_o(wire_ram0_we_i),
.s0_cyc_o(wire_ram0_cyc_i),
.s0_stb_o(wire_ram0_stb_i),
.s0_ack_i(wire_ram0_ack_o),
.s0_err_i(0),
.s0_rty_i(0),
//.s0_cab_o(),
// Slave 1 Interface
.s1_data_i(wire_gpio_data_o),
.s1_data_o(wire_gpio_data_i),
.s1_addr_o(wire_gpio_addr_i),
.s1_sel_o(wire_gpio_sel_i),
.s1_we_o(wire_gpio_we_i),
.s1_cyc_o(wire_gpio_cyc_i),
.s1_stb_o(wire_gpio_stb_i),
.s1_ack_i(wire_gpio_ack_o),
.s1_err_i(wire_gpio_err_o),
.s1_rty_i(0),
//.s1_cab_o(),
// Slave 2 Interface
.s2_data_i(wire_uart_data_o),
.s2_data_o(wire_uart_data_i),
.s2_addr_o(wire_uart_addr_i),
.s2_sel_o(wire_uart_sel_i),
.s2_we_o(wire_uart_we_i),
.s2_cyc_o(wire_uart_cyc_i),
.s2_stb_o(wire_uart_stb_i),
.s2_ack_i(wire_uart_ack_o),
.s2_err_i(0),
.s2_rty_i(0)//,
//.s0_cab_o(),
);
ram0_top u_ram0(
.clk_i(clk_i),
.rst_i(rst),
.wb_stb_i(wire_ram0_stb_i),
.wb_cyc_i(wire_ram0_cyc_i),
.wb_ack_o(wire_ram0_ack_o),
.wb_addr_i(wire_ram0_addr_i),
.wb_sel_i(wire_ram0_sel_i),
.wb_we_i(wire_ram0_we_i),
.wb_data_i(wire_ram0_data_i),
.wb_data_o(wire_ram0_data_o)
);
gpio_top u_gpio(
// WISHBONE Interface
.wb_clk_i(clk_i),
.wb_rst_i(rst),
.wb_cyc_i(wire_gpio_cyc_i),
.wb_adr_i(wire_gpio_addr_i),
.wb_dat_i(wire_gpio_data_i),
.wb_sel_i(wire_gpio_sel_i),
.wb_we_i(wire_gpio_we_i),
.wb_stb_i(wire_gpio_stb_i),
.wb_dat_o(wire_gpio_data_o),
.wb_ack_o(wire_gpio_ack_o),
.wb_err_o(wire_gpio_err_o),
.wb_inta_o(wire_gpio_interrupt),
//`ifdef GPIO_AUX_IMPLEMENT
// // Auxiliary inputs interface
// .aux_i(),
//`endif // GPIO_AUX_IMPLEMENT
// External GPIO Interface
.ext_pad_i({16'b0,SW}),
.ext_pad_o(LEDR),
.ext_padoe_o()//,
//`ifdef GPIO_CLKPAD
// .clk_pad_i()
//`endif
);
uart_top u_uart(
.wb_clk_i(clk_i),
// Wishbone signals
.wb_rst_i(rst),
.wb_adr_i(wire_uart_addr_i[4:0]),
.wb_dat_i(wire_uart_data_i),
.wb_dat_o(wire_uart_data_o),
.wb_we_i(wire_uart_we_i),
.wb_stb_i(wire_uart_stb_i),
.wb_cyc_i(wire_uart_cyc_i),
.wb_ack_o(wire_uart_ack_o),
.wb_sel_i(wire_uart_sel_i),
.int_o(wire_uart_interrupt), // interrupt request
// UART signals
// serial input/output
.stx_pad_o(uart_txd),
.srx_pad_i(uart_rxd),
// modem signals
.rts_pad_o(),
.cts_pad_i(1'b0),
.dtr_pad_o(),
.dsr_pad_i(1'b0),
.ri_pad_i(1'b0),
.dcd_pad_i(1'b0)//,
//`ifdef UART_HAS_BAUDRATE_OUTPUT
// .baud_o()
//`endif
);
endmodule
修改or1200_sopc.v文件:
//small sopc with openrisc
//`include "or1200_defines.v"
module or1200_sopc
(
//////////////////// Clock Input ////////////////////
CLOCK_27, // On Board 27 MHz
CLOCK_50, // On Board 50 MHz
//////////////////// Push Button ////////////////////
KEY, // Pushbutton[3:0]
//////////////////// DPDT Switch ////////////////////
SW, // Toggle Switch[17:0]
//////////////////////// LED ////////////////////////
LEDR, // LED Red[17:0]
//////////////////////// UART ////////////////////////
UART_TXD, // UART Transmitter
UART_RXD//, // UART Receiver
);
//////////////////////// Clock Input ////////////////////////
input CLOCK_27; // On Board 27 MHz
input CLOCK_50; // On Board 50 MHz
//////////////////////// Push Button ////////////////////////
input [3:0] KEY; // Pushbutton[3:0]
//////////////////////// DPDT Switch ////////////////////////
input [17:0] SW; // Toggle Switch[17:0]
//////////////////////////// LED ////////////////////////////
output [17:0] LEDR; // LED Red[17:0]
//////////////////////////// UART ////////////////////////////
output UART_TXD; // UART Transmitter
input UART_RXD; // UART Receiver
wire CPU_RESET;
wire clk_25,clk_10;
Reset_Delay delay1 (.iRST(KEY[0]),.iCLK(CLOCK_50),.oRESET(CPU_RESET));
cpu_pll pll0 (.inclk0(CLOCK_50),.c0(clk_25),.c1(clk_10));
or1200_sys or1200(
.clk_i(clk_25),
.rst_n(CPU_RESET),
// buttons
.SW(SW[15:0]),
// segments
.LEDR(LEDR[17:0]),
// uart interface
.uart_rxd(UART_RXD),
.uart_txd(UART_TXD)//,
);
endmodule
仿真UART时需要用到UART的接收器核uart_rx。将uart_rx.v文件(从张老师那拷过来的,也不清楚在哪里可以找到)拷贝到or1200_sopc文件夹下,并修改or1200_sopc_tb.v文件
`timescale 1ns/100ps
module or1200_sopc_tb();
reg CLOCK_50;
reg CLOCK_27;
reg [3:0] KEY;
reg [17:0] SW;
wire [17:0] LEDR;
wire UART_TXD;
reg UART_RXD;
initial begin
CLOCK_50 = 1'b0;
forever #10 CLOCK_50 = ~CLOCK_50;
end
initial begin
KEY[0] = 1'b0;
#50 KEY[0]= 1'b1;
end
initial begin
SW = 18'h1234;
end
or1200_sopc or1200_sopc_inst
(
//////////////////// Clock Input ////////////////////
.CLOCK_27(CLOCK_27), // On Board 27 MHz
.CLOCK_50(CLOCK_50), // On Board 50 MHz
//////////////////// Push Button ////////////////////
.KEY(KEY), // Pushbutton[3:0]
//////////////////// DPDT Switch ////////////////////
.SW(SW), // Toggle Switch[17:0]
//////////////////////// LED ////////////////////////
.LEDR(LEDR), // LED Red[17:0]
//////////////////////// UART ////////////////////////
.UART_TXD(UART_TXD), // UART Transmitter
.UART_RXD(UART_RXD)//, // UART Receiver
);
reg baudclk;
//baudclk : 1000000000/(16*baud_rate), when baud_rate=9600, is 6510
//`define BAUDCLK_HALF_PERIOD 3255
`define BAUDCLK_HALF_PERIOD 271
initial begin
baudclk = 0;
forever # `BAUDCLK_HALF_PERIOD baudclk = ~baudclk;
end
uart_rx u_uart_rx (
.reset( ~KEY[0] ),
.rxclk( baudclk ),
.rx_in( UART_TXD)
);
endmodule
修改vlog.args文件
+libext+.v
-vlog01compat
+acc
-y ./pll
-y ./ram
-y ./or1200
-y ./gpio
-y ./wb_conmax
-v altera_mf.v
-v 220model.v
-work ./work
//
// Test bench files
//
or1200_sopc_tb.v
//
// RTL files (gpio)
//
+incdir+./gpio
./gpio/gpio_top.v
./gpio/gpio_defines.v
//
// RTL files (top)
//
+incdir+../rtl
./or1200_sys.v
./or1200_sopc.v
./pll/cpu_pll.v
./Reset_Delay.v
./uart_rx.v
//
// wb_conmax
//
+incdir+./wb_conmax
./wb_conmax/wb_conmax_arb.v
./wb_conmax/wb_conmax_defines.v
./wb_conmax/wb_conmax_master_if.v
./wb_conmax/wb_conmax_msel.v
./wb_conmax/wb_conmax_pri_dec.v
./wb_conmax/wb_conmax_pri_enc.v
./wb_conmax/wb_conmax_rf.v
./wb_conmax/wb_conmax_slave_if.v
./wb_conmax/wb_conmax_top.v
//
// RTL files (or1200)
//
+incdir+./or1200
./or1200/or1200_defines.v
./or1200/or1200_iwb_biu.v
./or1200/or1200_wb_biu.v
./or1200/or1200_ctrl.v
./or1200/or1200_cpu.v
./or1200/or1200_rf.v
./or1200/or1200_rfram_generic.v
./or1200/or1200_alu.v
./or1200/or1200_lsu.v
./or1200/or1200_operandmuxes.v
./or1200/or1200_wbmux.v
./or1200/or1200_genpc.v
./or1200/or1200_if.v
./or1200/or1200_freeze.v
./or1200/or1200_sprs.v
./or1200/or1200_top.v
./or1200/or1200_pic.v
./or1200/or1200_pm.v
./or1200/or1200_tt.v
./or1200/or1200_except.v
./or1200/or1200_dc_top.v
./or1200/or1200_dc_fsm.v
./or1200/or1200_reg2mem.v
./or1200/or1200_mem2reg.v
./or1200/or1200_dc_tag.v
./or1200/or1200_dc_ram.v
./or1200/or1200_ic_top.v
./or1200/or1200_ic_fsm.v
./or1200/or1200_ic_tag.v
./or1200/or1200_ic_ram.v
./or1200/or1200_immu_top.v
./or1200/or1200_immu_tlb.v
./or1200/or1200_dmmu_top.v
./or1200/or1200_dmmu_tlb.v
./or1200/or1200_amultp2_32x32.v
./or1200/or1200_gmultp2_32x32.v
./or1200/or1200_cfgr.v
./or1200/or1200_du.v
./or1200/or1200_sb.v
./or1200/or1200_sb_fifo.v
./or1200/or1200_mult_mac.v
./or1200/or1200_qmem_top.v
./or1200/or1200_dpram_32x32.v
./or1200/or1200_spram_2048x32.v
./or1200/or1200_spram_2048x32_bw.v
./or1200/or1200_spram_2048x8.v
./or1200/or1200_spram_512x20.v
./or1200/or1200_spram_256x21.v
./or1200/or1200_spram_1024x8.v
./or1200/or1200_spram_1024x32.v
./or1200/or1200_spram_1024x32_bw.v
./or1200/or1200_spram_64x14.v
./or1200/or1200_spram_64x22.v
./or1200/or1200_spram_64x24.v
./or1200/or1200_xcv_ram32x8d.v
//
// RTL files (uart16550)
//
+incdir+./uart16550
./uart16550/raminfr.v
./uart16550/uart_debug_if.v
./uart16550/uart_tfifo.v
./uart16550/uart_rfifo.v
./uart16550/uart_receiver.v
./uart16550/uart_regs.v
./uart16550/uart_transmitter.v
./uart16550/uart_wb.v
./uart16550/uart_top.v
./uart16550/uart_sync_flops.v
//
// Library files
//
//altera_mf.v
加长sim.do中的run的时间
最终的文件目录
/or1200_sopc
/or1200
/wb_conmax
/gpio
/ram
/pll
/uart16550
or1200_sopc.v
or1200_sys.v
or1200_sopc_tb.v
Reset_Delay.v
altera_mf.v
220model.v
uart_rx.v
vlog –f vlog.args调试至硬件没有错误
下面修改软件代码。
从demo_or32_sw.zip工程中把uart.h和uart.c拷贝到software目录下,把gpio_or1200.c重命名为or1200_sopc.c并修改其中内容
#include "orsocdef.h"
#include "board.h"
#include "uart.h"
int
main (void)
{
long gpio_in;
REG32 (RGPIO_OE) = 0xffffffff;
uart_init();
uart_print_str("Hello World!\n");
while(1){
gpio_in = REG32 (RGPIO_IN);
gpio_in = gpio_in & 0x0000ffff;
REG32 (RGPIO_OUT) = gpio_in;
}
return 0;
}
执行make all 生成ram0.mif文件,拷贝到onchip-ram的初始化目录。
仿真,在dos窗口下运行
# vsim –do sim.do
仿真结果,在命令行窗口处会显示:
# H
# e
# l
# l
# o
#
# W
# o
# r
# l
# d
# !
在DE2平台上验证,参考(原创)基于or1200最小sopc系统搭建(二)--QuartuII工程及DE2平台下载构建quartusII工程。生成or1200_sopc.sof文件。
设置超级终端
将生成的or1200_sopc.sof文件下载到DE2中。
在超级终端上显示
有乱码。可以设置一下超级终端属性。
文件à属性à设置àASCII码设置à将传入的数据转换为7位的ASCII码
按复位键KEY[0],在超级终端上显示。
or1200的最小系统先到这里,此后有时间陆续加入opencores上的其它开源组件。
下面捣鼓一下aemb吧。
仿真源码:sopc_simulation_hw_sw.7zQuartusII工程源码:or1200_sopc_uart.7z