上位机最最基本有两个函数,如下:
//tested ok
int ejtag_read_back(char*buff,unsigned int bytes)//buff 长度将512的整数倍
{
printf("enter ejtag_read_back >>>>> bytes = %d" ,bytes);
char tmp[20];
unsigned int cmd ;
unsigned int i,t ;
cmd=6<<25 ;
i=align(bytes,4);//对齐
cmd |= i ; //将读会的字节数是被4整除
fill_byte(cmd,tmp); //
t=align(i,512);//数据包对齐
cmd=7<<25 ;//发送填充命令。
cmd|=(t-i);//填充数量是以字节对单位。
fill_byte(cmd,&tmp[4]);
if (t==i) t=4;else t=8;
#ifdef VC_TESTif((t-i)!=0)printf("\npadding data len %d\n",t-i);
else printf("\nno padding data\n",t-i);
lw_usb_write(tmp,t);
lw_usb_write(tmp,0);
i=lw_usb_read(buff,t);
///getchar () ;
#else
usb_buffer_write(tmp,t) ;
LOG_INFO(" ejtag_read_back write len = %d",t) ;
usb_buffer_write(NULL,0);
i=usb_bulk_read(loongsonejtag_jtag_handle->usb_handle,0x86,buff,t,5000);
LOG_INFO(" ejtag_read_back read len = %d",t) ;
#endif
LOG_INFO("\nejtag_read_back > usb_read result is %d\n",(int)i);
//for(i=0;i<bytes;++i) LOG_INFO("0x%02x ",(unsigned char )buff[i]);
return i ;
}
上面代码的基本操作单位是字节。首先使用6号指令读写回FIFO,之后不够512字节的使用7号指令进行填充,再看一下对应NIOS里面处理代码:
i=usb_rd_u32();
op_code=i>>25 ;
{
t=i&0xffffff; t>>=2;///if(i&3)t++;
if (op_code ==7 )while(t--) usb_wr_u32(EJTAG_BACK_FIFO_USEDW);
if (op_code ==6 )
{
while(t--){
while(EJTAG_STATUS&1);
usb_wr_u32(EJTAG_FIFO_DATA);
}
}
}
而在JTAG控制器的VERILOG代码中,最后一个字不足32位也是按照32位写回的:
always@ (posedge clk)
if (bit_syn&op_wb_r)
back_fifo_wr<= ((state == 'h322 )&&(~|sft32)) || (state == 'h325) ;
else
back_fifo_wr<=0;
这里也是按照字节处理的,明天硬件测试时候可以在上位机将6号指令换成7号指令。看看是否能够在不进行JTAG操作的时候顺利读写。
///tested ok
int ejtag_scan(unsigned int ir0dr1,unsigned int wb,char*p,unsigned int bits)
{
printf("enter ejtag_scan >>>> \n");
printf("bits = %d ir0dr1=%d wb=%d\n",bits,ir0dr1,wb);
unsigned int cmd,i,j,t ;
char*tmp=malloc(bits/8+32);
cmd=(ir0dr1)?(4<<25):(3<<25);
if(wb)cmd|=1<<24 ;
cmd|=bits ;
fill_byte(cmd,tmp);
j=bits/8+1 ;//字节拷贝,
for(i=0;i<j;i++)tmp[4+i]=p[i];
t=align(bits,32);//32位对齐
t=t/8 ;
t+=4 ;//加上命令的四个字节
#ifdef VC_TEST
lw_usb_write(tmp,t);
lw_usb_write(NULL,0);
printf("write data to usb len = %d!\n",t);
getchar();
#else
usb_buffer_write(tmp,t);//是否立即写回了。
#endif
free(tmp);
printf("return from ejtag_scan <<<<<<< \n");
return 1 ;
}
以下是NIOS的对应处理片段。
else if((op_code==3)||(op_code==4))
{
EJTAG_FIFO_DATA=i ;
t=i&0xffffff ;
t=t>>5 ;
if(i&31)t++;//首先转变成32个BIT,多少个字
for(i=0;i<t;++i)
{
while(EJTAG_STATUS&2); //1:wb_dout <= {29'b0,state_idle,front_fifo_full,back_fifo_empty}
EJTAG_FIFO_DATA=usb_rd_u32();
}//将这写字都发送给JTAG控制器。
}
这里是以BITS为单位。没有发现什么BUG。
今天实现的现象是无法回读,通过以上分析,我觉得比较妥当的入手点是ejtag_read_back,这个函数,将6号指令修改成7号无条件回读。看是否能够立即回读回数据来,如果能。如果不能,找基本通讯对话的问题,如果能则继续实验看看JTAG控制器是否存在问题造成了写会FIFO内部没有足够的数。
//
代码中1处小小修改:
static int usb_read_sync2()
{
int ret=1 ;
printf("eneter usb_read_sync2() >>>>>>>> \n");
printf(" usb_read_sync2() >>>usb_expect_read = %d \n",usb_expect_read);
if(usb_expect_read)
{
// fpga_info_ejtag(7,0,NULL);
//set read back command
// usb_write_flush();
if(usb_read_buffer)free(usb_read_buffer);
usb_read_buffer=malloc(usb_expect_read + 512 ); //buffer 不至于因为512整数读书的内存错误。
// ret=usb_bulk_read(loongsonejtag_jtag_handle->u
这个问题解决之后将考虑将把7号命令做成加速器。不需要NIOS处理器循环操作,只告诉加速器需要填充多少个32BIT的字就可以。
加速器做成功之后就可以考虑进行实际的JTAG ID的读取。如果读取顺利就可以接入OPENOCD进行GDB操作了。
<------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
2013-8-13
bug已经解决,是10号指令的处理有问题,修改了NIOS代码。解决。
今天调试成功,暂时用8MHZ的TCK速度连通了OPENOCD。调试LS1板子没有问题。
今天晚上回家写了一个小小的加速器,很精简,很巧妙。
module padding_fsm(
input clk,
input fifo_full,
input wr,
input [15:0]din,
output reg wr_fifo,idle
);
reg [15:0] cnt;
always@(posedge clk)
if (wr)cnt<=din;
else if (wr_fifo) cnt<=cnt-1;
always@(*) wr_fifo = (~|cnt ) & (~fifo_full);
always @ (posedge clk)idle<=~|cnt;
endmodule
是自动添填充FIFO的小加速器,没有延迟,不占用另外周期。
以下是调用此加速器的顶层:
module wb_ejtag(
input clk,rst,clk_2x,
input wb_wr,
input[1:0] wb_addr,
input [31:0]wb_din,
output reg [31:0]wb_dout,
input wb_rd,
input ejtag_tdo,
output ejtag_tdi,ejtag_tck,ejtag_tms,
output reg ejtag_led,ejtag_rrst,ejtag_trst
);
wire state_idle;
wire front_fifo_wr, front_fifo_full;
wire [31:0] front_fifo_d;
reg back_fifo_rd;
wire back_fifo_empty ;
wire [31:0] back_fifo_q;
reg front_fifo_wrr;
assign front_fifo_d = wb_din ;
assign front_fifo_wr = (wb_addr[1:0] == 0) & wb_wr &(~front_fifo_wrr);
wire [15:0]back_fifo_usedw;
always@ (posedge clk)front_fifo_wrr<=front_fifo_wr;
wire wr_front_fifo_by_padding_fsm ;
ejtag_top uu(
.clk(clk),
.clk_2x(clk_2x),
.rst(rst),
.state_idle(state_idle),
.front_fifo_wr(front_fifo_wr | wr_front_fifo_by_padding_fsm),
.front_fifo_full(front_fifo_full),
.front_fifo_d(front_fifo_d),
.back_fifo_rd(back_fifo_rd),
.back_fifo_empty(back_fifo_empty),
.back_fifo_q(back_fifo_q),
.ejtag_tck(ejtag_tck),
.ejtag_tdi(ejtag_tdi),
.ejtag_tms(ejtag_tms),
.ejtag_tdo(ejtag_tdo),
.back_fifo_usedw(back_fifo_usedw)
);
wire wr_padding_fsm;
wire padding_fsm_idle ;
padding_fsm padding_fsm(
.clk(clk),
.fifo_full(front_fifo_full),
.wr(wr_padding_fsm),
.din(wb_din[15:0]),
.wr_fifo(wr_front_fifo_by_padding_fsm),
.idle(padding_fsm_idle)
);
assign wr_padding_fsm = (wb_addr[1:0] == 2) & wb_wr ;
//-----------------------------------------
reg wb_rdr,wb_rdrr;
always @ (*)wb_rdr<= wb_rd & (wb_addr[1:0] == 0);
always @ (posedge clk)wb_rdrr<= wb_rdr;
always @ (*)back_fifo_rd = {wb_rdrr,wb_rdr}==2'b01;
//-----------------------------------------
always @ (posedge clk) if((wb_wr)&(wb_addr == 1)) ejtag_led <= wb_din[0];
always @ (posedge clk) if((wb_wr)&(wb_addr == 1)) ejtag_trst <= wb_din[1];
always @ (posedge clk) if((wb_wr)&(wb_addr == 1)) ejtag_rrst <= wb_din[2];
always @ (posedge clk)
case (wb_addr)
0:wb_dout <= back_fifo_q;
1:wb_dout <= {28'b0,padding_fsm_idle,state_idle,front_fifo_full,back_fifo_empty} ; //some state
2:wb_dout <= {16'b0 , back_fifo_usedw} ; //some state
default
wb_dout<= 'hx ;
endcase
endmodule
用了一个或逻辑实现了NIOS和加速器的读写的统一。