omam138/upp/fpga
2019-07-13 15:51 发布
生成海报
uPP通信(2)---FPGA篇 2013-01-13 09:59:32
分类:
嵌入式
系统架构
本系统组成如下图, FPGA
挨个读取 24
个 AD
通道中的数据,然后通过 UPP
方式传送给 OMAPL138
中的 DSP
核,经过一系列运算, DSP
核通过 DSPLINK
方式将数据送到 ARM
核。
FPGA
数据读取、存储、传送、数据识别问题
因为 OMAPL138
需要识别传送上来的数据是对应哪个通道的。所以 FPGA
对数据必须做一些处理以便于 OMAPL138
对数据分门别类。
方法一:
在 FPGA
中生成一个 FIFO
,挨个读取 24
个 AD
通道中的数据按次序存放到 FIFO
中, FIFO
中存放满预定大小的数据量时再上传给 OMAPL138
,这样 OMAPL138
就知道第一个数据是对应通道 1
的,第二个数据是对应通道 2
的。
优点:简单,容易实现
缺点:如果其中一个数据出错或者漏传,那后面的一大堆数据都会被错误归类。
方法二:
AD
通道输出数据是 16
位,将其扩展为 32
位,高 16
位作为标志位。例如,如果第一个 AD
通道读出来的 0xDE33,
那扩展为 32
位时其数据为 0x0001DE33
。 OMAPL138
通过其高 16
位辨别这个数据是哪个通道的。
优点:不再像方法一担心数据传错了,传错也不会危害到整体。
缺点: OMAPL138
的 UPP
通信时 16
位的数据线,原来是需要传送数据,现在还要传送标志数据,这样直接导致传输效率打 5
折。但是对于能够到达 150MB/s
吞吐量的 UPP
来说,就算传输只能达到 50%
,也是能满足我目前这个系统的。
读取 AD
:
以下是读取 ad
的代码,状态机的状态比较多,比较麻烦。
点击(
此处 )折叠或打开
module ads_ddio (
clk,
rst,
eoc,
datain,
dataout,
f_ncs,
f_nrd,
fifo_wr,
f_c1,
f_c2,
f_c3,
f_c4,
f_c5,
f_c6
) ;
input clk, rst;
input[ 1: 0] eoc;
input[ 15: 0] datain;
output f_c1, f_c2, f_c3, f_c4, f_c5, f_c6;
output[ 1: 0] f_ncs;
output[ 1: 0] f_nrd;
output fifo_wr;
output[ 31: 0] dataout;
reg[ 7: 0] counter;
reg[ 31: 0] data_reg;
reg state;
reg[ 1: 0] eoc1;
reg[ 5: 0] cstate, nstate;
reg[ 1: 0] f_nrd_reg, f_ncs_reg;
reg fifo_wr_reg;
parameter SET_COUNT = 8' hff,
SET_CSRD_C1UA = 8' d23,
SET_DATA_C1UA = 8' d24,
SET_CSRD_C1UB = 8' d26,
SET_DATA_C1UB = 8' d27,
SET_CSRD_C1UC = 8' d29,
SET_DATA_C1UC = 8' d30,
SET_CSRD_C1IA = 8' d32,
SET_DATA_C1IA = 8' d33,
SET_CSRD_C1IB = 8' d35,
SET_DATA_C1IB = 8' d36,
SET_CSRD_C1IC = 8' d38,
SET_DATA_C1IC = 8' d39,
SET_CSRD_C2UA = 8' d41,
SET_DATA_C2UA = 8' d42,
SET_CSRD_C2UB = 8' d44,
SET_DATA_C2UB = 8' d45,
SET_CSRD_C2UC = 8' d47,
SET_DATA_C2UC = 8' d48,
SET_CSRD_C2IA = 8' d50,
SET_DATA_C2IA = 8' d51,
SET_CSRD_C2IB = 8' d53,
SET_DATA_C2IB = 8' d54,
SET_CSRD_C2IC = 8' d56,
SET_DATA_C2IC = 8' d57,
SET_FIFO_DATA = 8' d60, / / 上个状态+ 3
SET_IDLE = 8' d62;
parameter IDLE = 6' d0,
CSRDN_C1UA = 6' d1,
DATA_C1UA = 6' d2,
DATA1_C1UA = 6' d3,
CSRDN_C1UB = 6' d4,
DATA_C1UB = 6' d5,
DATA1_C1UB = 6' d6,
CSRDN_C1UC = 6' d7,
DATA_C1UC = 6' d8,
DATA1_C1UC = 6' d9,
CSRDN_C1IA = 6' d10,
DATA_C1IA = 6' d11,
DATA1_C1IA = 6' d12,
CSRDN_C1IB = 6' d13,
DATA_C1IB = 6' d14,
DATA1_C1IB = 6' d15,
CSRDN_C1IC = 6' d16,
DATA_C1IC = 6' d17,
DATA1_C1IC = 6' d18,
CSRDN_C2UA = 6' d19,
DATA_C2UA = 6' d20,
DATA1_C2UA = 6' d21,
CSRDN_C2UB = 6' d22,
DATA_C2UB = 6' d23,
DATA1_C2UB = 5' d24,
CSRDN_C2UC = 6' d25,
DATA_C2UC = 6' d26,
DATA1_C2UC = 6' d27,
CSRDN_C2IA = 6' d28,
DATA_C2IA = 6' d29,
DATA1_C2IA = 6' d30,
CSRDN_C2IB = 6' d31,
DATA_C2IB = 6' d32,
DATA1_C2IB = 6' d33,
CSRDN_C2IC = 6' d34,
DATA_C2IC = 6' d35,
DATA1_C2IC = 6' d36,
FIFO_DATA = 6' d37;
wire csrd_n_c1ua_req;
wire csrd_n_c1ub_req;
wire csrd_n_c1uc_req;
wire csrd_n_c1ia_req;
wire csrd_n_c1ib_req;
wire csrd_n_c1ic_req;
wire csrd_n_c2ua_req;
wire csrd_n_c2ub_req;
wire csrd_n_c2uc_req;
wire csrd_n_c2ia_req;
wire csrd_n_c2ib_req;
wire csrd_n_c2ic_req;
wire data_c1ua_req;
wire data_c1ub_req;
wire data_c1uc_req;
wire data_c1ia_req;
wire data_c1ib_req;
wire data_c1ic_req;
wire data_c2ua_req;
wire data_c2ub_req;
wire data_c2uc_req;
wire data_c2ia_req;
wire data_c2ib_req;
wire data_c2ic_req;
wire fifo_data_req;
wire idle_req;
assign f_c1 = 1' b1;
assign f_c2 = 1' b0;
assign f_c3 = 1' b1;
assign f_c4 = 1' b0;
assign f_c5 = 1' b0;
assign f_c6 = 1' b0;
assign dataout = data_reg;
assign csrd_n_c1ua_req = ( counter = = SET_CSRD_C1UA) ;
assign csrd_n_c1ub_req = ( counter = = SET_CSRD_C1UB) ;
assign csrd_n_c1uc_req = ( counter = = SET_CSRD_C1UC) ;
assign csrd_n_c1ia_req = ( counter = = SET_CSRD_C1IA) ;
assign csrd_n_c1ib_req = ( counter = = SET_CSRD_C1IB) ;
assign csrd_n_c1ic_req = ( counter = = SET_CSRD_C1IC) ;
assign csrd_n_c2ua_req = ( counter = = SET_CSRD_C2UA) ;
assign csrd_n_c2ub_req = ( counter = = SET_CSRD_C2UB) ;
assign csrd_n_c2uc_req = ( counter = = SET_CSRD_C2UC) ;
assign csrd_n_c2ia_req = ( counter = = SET_CSRD_C2IA) ;
assign csrd_n_c2ib_req = ( counter = = SET_CSRD_C2IB) ;
assign csrd_n_c2ic_req = ( counter = = SET_CSRD_C2IC) ;
assign data_c1ua_req = ( counter = = SET_DATA_C1UA) ;
assign data_c1ub_req = ( counter = = SET_DATA_C1UB) ;
assign data_c1uc_req = ( counter = = SET_DATA_C1UC) ;
assign data_c1ia_req = ( counter = = SET_DATA_C1IA) ;
assign data_c1ib_req = ( counter = = SET_DATA_C1IB) ;
assign data_c1ic_req = ( counter = = SET_DATA_C1IC) ;
assign data_c2ua_req = ( counter = = SET_DATA_C2UA) ;
assign data_c2ub_req = ( counter = = SET_DATA_C2UB) ;
assign data_c2uc_req = ( counter = = SET_DATA_C2UC) ;
assign data_c2ia_req = ( counter = = SET_DATA_C2IA) ;
assign data_c2ib_req = ( counter = = SET_DATA_C2IB) ;
assign data_c2ic_req = ( counter = = SET_DATA_C2IC) ;
assign fifo_data_req = ( counter = = SET_FIFO_DATA) ;
assign idle_req = ( counter = = SET_IDLE) ;
assign f_nrd[ 0] = ( cstate = = DATA_C1UA | | cstate = = CSRDN_C1UA | | cstate = = DATA_C1UB | | cstate = = CSRDN_C1UB | | cstate = = DATA_C1UC | | cstate = = CSRDN_C1UC | | cstate = = DATA_C1IA | | cstate = = CSRDN_C1IA | | cstate = = DATA_C1IB | | cstate = = CSRDN_C1IB | | cstate = = DATA_C1IC | | cstate = = CSRDN_C1IC ) ? f_nrd_reg[ 0] : 1' b1;
assign f_ncs[ 0] = ( cstate = = DATA_C1UA | | cstate = = CSRDN_C1UA | | cstate = = DATA_C1UB | | cstate = = CSRDN_C1UB | | cstate = = DATA_C1UC | | cstate = = CSRDN_C1UC | | cstate = = DATA_C1IA | | cstate = = CSRDN_C1IA | | cstate = = DATA_C1IB | | cstate = = CSRDN_C1IB | | cstate = = DATA_C1IC | | cstate = = CSRDN_C1IC ) ? f_ncs_reg[ 0] : 1' b1;
assign f_nrd[ 1] = ( cstate = = DATA_C2UA | | cstate = = CSRDN_C2UA | | cstate = = DATA_C2UB | | cstate = = CSRDN_C2UB | | cstate = = DATA_C2UC | | cstate = = CSRDN_C2UC | | cstate = = DATA_C2IA | | cstate = = CSRDN_C2IA | | cstate = = DATA_C2IB | | cstate = = CSRDN_C2IB | | cstate = = DATA_C2IC | | cstate = = CSRDN_C2IC ) ? f_nrd_reg[ 1] : 1' b1;
assign f_ncs[ 1] = ( cstate = = DATA_C2UA | | cstate = = CSRDN_C2UA | | cstate = = DATA_C2UB | | cstate = = CSRDN_C2UB | | cstate = = DATA_C2UC | | cstate = = CSRDN_C2UC | | cstate = = DATA_C2IA | | cstate = = CSRDN_C2IA | | cstate = = DATA_C2IB | | cstate = = CSRDN_C2IB | | cstate = = DATA_C2IC | | cstate = = CSRDN_C2IC ) ? f_ncs_reg[ 1] : 1' b1;
assign fifo_wr = ( / * cstate = = DATA_C1UA | | * / cstate = = DATA_C1UB | | cstate = = DATA_C1UC | | cstate = = DATA_C1IA | | cstate = = DATA_C1IB | | cstate = = DATA_C1IC | | cstate = = DATA_C2UA | | cstate = = DATA_C2UB | | cstate = = DATA_C2UC | | cstate = = DATA_C2IA | | cstate = = DATA_C2IB | | cstate = = DATA_C2IC | | cstate = = FIFO_DATA ) ? fifo_wr_reg : 1' b0;
always @ ( posedge clk or negedge rst)
if ( ! rst)
cstate < = IDLE;
else
cstate < = nstate;
always @ ( cstate or fifo_data_req or csrd_n_c1ua_req or data_c1ub_req or csrd_n_c1uc_req or data_c1ia_req or data_c1ib_req or data_c1ic_req or csrd_n_c2ua_req or data_c2ub_req or csrd_n_c2uc_req or data_c2ia_req or data_c2ib_req or data_c2ic_req)
case ( cstate)
IDLE:
if ( csrd_n_c1ua_req)
nstate < = CSRDN_C1UA;
else
nstate < = IDLE;
CSRDN_C1UA:
if ( data_c1ua_req)
nstate < = DATA_C1UA;
else
nstate < = CSRDN_C1UA;
DATA_C1UA:
nstate < = DATA1_C1UA;
DATA1_C1UA:
if ( csrd_n_c1ub_req)
nstate < = CSRDN_C1UB;
else
nstate < = DATA1_C1UA;
CSRDN_C1UB:
if ( data_c1ub_req)
nstate < = DATA_C1UB;
else
nstate < = CSRDN_C1UB;
DATA_C1UB:
nstate < = DATA1_C1UB;
DATA1_C1UB:
if ( csrd_n_c1uc_req)
nstate < = CSRDN_C1UC;
else
nstate < = DATA1_C1UB;
CSRDN_C1UC:
if ( data_c1uc_req)
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮