应聘FPGA硬件职位的一道笔试题,百思不得其解

题目是这样的:

       DSP和FPGA组成一个系统的核心,FPGA要响应外界8个IO端口,当检测到8个IO中有从高到低跳变时,产生一个从高到低的中断信号(XINT)给DSP,DSP通过EMIF读取FPGA中的一个寄存器来判断是那一个IO发生了跳变,最后要使XINT变高。

      题目大概是这样的,系统结构给出了,要用HDL语言写一个框架结构。

      主要是最后使XINT变高很难!!!
我也来说两句 查看全部回复

最新回复

  • windzjy (2008-8-11 17:46:24)

    为什么使它变高很难呢?
    你判断XINT的下降延,并且读取寄存器之后为高就是了,可能没有明白你的意思
  • qingchuyu (2008-8-11 18:29:52)

    it will use CPU or DSP to clear the flag bit whenthe interrupt is acknowledged.
  • yuananr (2008-8-11 22:16:34)

    没接触过EMIF总线,不过根据dsp通过EMIF总线读FPGA的读写控制信号的时序,应该可以方便地来控制XINT。
  • fwang (2008-8-11 22:27:32)

    是个典型的DSP- FPGA中断-查询通信方式, 无非做几个模块,一个是外部IO处理模块,另外一个是中断产生模块,再通过EMIF总线挂接个寄存器堆模块,记得做个中断清除就行。我想这题目不要求你写的多完美,因为根本就没有时间写完整。给出框架就好了,还是很简单的。
  • qinxg (2008-8-12 11:21:04)

    就是用一个时钟来检测IO,EMIF的跳变即可.
  • edazoujie (2008-8-12 12:23:45)

    其实这个题目还是很有推敲的:
    (1) 这个中断XINT只能是在某个IO出现从高到低的跳变才出现从高到低的跳变,是一个边沿触发逻辑,用时钟检测是不可取的,如果有一个IO本来就是低电平的话,就不能触发中断,一定要从高到低的跳变才能触发XINT,如果要用时钟检测就要用类似MCU检测外部中断的方式了
    (2)如何在DSP响应后使XINT拉高?这个很麻烦, 我的思路是:设立IO_REG[7:0]和XINT_REG[7:0]这2个状态寄存器,IO_REG[7:0]只反应当前8个IO的电平情况,XINT_REG[7:0中各位只有对应IO出现负跳变的时候才置为0,复位时为1,而XINT <= &XINT_REG,这样XINT的负跳变是实现了,但如何使XINT_REG[7:0]中的响应位再置为1呢?
  • ql_smbj (2008-8-12 12:46:05)

    要使XINT变高, 俺个人觉得可以采用下面的办法:

            设置一个状态寄存器state_reg[7..0],用于DSP与FPGA之间的通讯状态。DSP读完中断,并判别出是哪个IO有跳变之后, 向状态寄存器state_reg[7..0]发送命令,使得state_reg(0)=1,在FPGA内部可以命令: XINT <= XINT + state_reg(0)(可以设置state_reg[7..0]的初始状态为0xff)。
  • raulyrx (2008-8-12 12:46:51)

    QUOTE:

    原帖由 edazoujie 于 2008-8-12 12:23 发表
    其实这个题目还是很有推敲的:
    (1) 这个中断XINT只能是在某个IO出现从高到低的跳变才出现从高到低的跳变,是一个边沿触发逻辑,用时钟检测是不可取的,如果有一个IO本来就是低电平的话,就不能触发中断,一定要从 ...
    针对(1),可以用时钟检测,而且也是比较好的解决方案,就是类似gpio一样,进来的信号delay 1ff(一般delay 2ff or 3ff  for romving glitch),之后与原信号取反相与,就可以把跳变的沿可以产生一个clock cycle的宽度,当然就可以判断是否产生中断信号并写入中断寄存器.只是这个中断信号是由高电平变到低电平而已.
    (2)不管运用什么总线,一般的中断寄存器是用2个reg做的,一个叫中断状态寄存器,一个叫中断mask寄存器,只要读取了该中断状态寄存器,该中断寄存器可以采用自动clear,就是只要被读取了,,就自动clear掉,或者写1来clear.至于mask主要是做系统需要的,可以把一些不必要的中断屏蔽掉.
    同意5楼的,说的已经很清楚了.
  • edazoujie (2008-8-12 13:08:47)

    谢谢提示,网上找了写资料,确实发现时钟检测IO是很好的解决方法,2个D触发器就可以实现!!!
  • tspen (2008-8-12 15:32:26)

    用两个d触发器就可以实现,xint 的清除与写入了。当外部io有由高向低的跳变时,置xint为低,当emif写fpga是,再置xint为高。
  • cryinrain_cug (2008-8-12 22:23:36)

    9楼的说的很清楚了
    其实找几个总线挂ip处理中断的例子看看会明白不少的
  • ilove314 (2008-8-12 23:02:58)

    设置一个INOUT口不就行了吗?
  • zfhlj (2008-8-12 23:33:36)

    DSP相应到中断后就通过EMIF口写个脉冲下来,然后FPGA就将这个脉冲先压窄,然后用压窄后的脉冲职位XINT寄存器,就可以让它变高了
  • ighost (2008-8-13 19:30:54)

    学习了
    谢谢
  • lflin (2008-8-15 16:50:51)

    always_comb
            case(current_state)
                    idle:
                            if(system_status != system_status_reg)
                                    next_state        =        int_out;
                            else
                                    next_state        =        idle;
                    int_out:
                            if((!bus.lbc_cs) && (!bus.lbc_oe) && (bus.lbc_addr == int_reg_1_addr))
                                    next_state        =        int_reg_out;
                            else
                                    next_state        =        int_out;
                    int_reg_out:
                            if((!bus.lbc_cs) && (!bus.lbc_oe) && (bus.lbc_addr == int_reg_1_addr))
                                    next_state        =        int_reg_out;
                            else
                                    next_state        =        int_clr;
                    int_clr:
                            next_state                =        idle;
                    default:
                            next_state                =        idle;
            endcase


    这个应该不是很麻烦吧,前几天刚做了这么个咚咚;
  • neptune1983 (2008-9-26 15:59:43)

    好像做过类似的东西,注意下就行了,另设一个寄存器用来标志读过没有就可以了,读过就置位
  • lightzhou (2008-10-06 11:34:08)

    检测到读的时候把数据放到双向数据总线上同时把xint拉高呀
    可以用一个状态机去控制
  • bupt_skywalker (2008-11-15 11:19:55)

    整理了一下,初学者,有什么问题欢迎指正!
    module detecting (i0,i1,i2,i3,i4,i5,i6,i7,clk,rst_n,xint,data,addr);



    parameter DSIZE = 8;

    parameter IDLE =0,INT_OUT=1,REG_OUT=2,INT_CLR=3;





    input i0;

    input i1;

    ...

    output xint;

    outout [DSIZE-1:0] data;



    reg i0_d;



    always@(posedge clk )

    i0_d<=i0;



    assign i0_pulse=(i0==1) and (i0_d==0);

    ...

    assign pulse =i0_pulse |i1_pulse |i2_pulse |i3_pulse |i4_pulse |i5_pulse |i6_pulse |i7_pulse;



    reg [1:0] current_state,next_state;

    always@(posedge clk or negedge rst_n)

    begin

    if (rst_n==0)

    current_state<=IDLE;

    else current_state<=next_state;

    end



    always@(current_state)

    begin

    next_state= current_state;

    case(current_state)

    IDLE: begin

       if (pulse==1) next_state=INT_OUT;

       else next_state= IDLE;

       end

    INT_OUT: begin

       if (addr==reg_addr) next_state=REG_OUT;

       else next_state = INT_OUT;

       end

    REG_OUT:begin

       if (addr==reg_addr) next_state=REG_OUT;

       else next_state = INT_CLR;

       end

    INT_CLR: next_state = IDLE;

    DEFAULT:next_state = IDLE;

    end case

    end

    always@()

    begin

    if (current_state==INT_OUT)

        xint=1'b1;

    else if (current_state== INT_CLR)

        xint=1'b0;

    end

    end module
  • yage1981 (2008-11-15 12:07:51)

    ******************************d
  • yuananr (2008-11-15 13:48:33)

    我也在做这个。我这里是这样做的:DSP检测到中断后,再向FPGA中对应的寄存器写1清零。写1清零的逻辑信号由地址比较信号、写信号和对应的数据位产生。