【问题标题】:problems writing to an avalon slave module写入 avalon 从模块的问题
【发布时间】:2017-08-18 23:04:25
【问题描述】:

我正在做一个项目,我需要能够将数据写入 avalon 从模块,以从运行在 DE0 板上的 nios 系统上的 2 个不同输入中选择数据。经过大量的辛勤工作,我一直无法将运行在 nios 核心上的 C 应用程序中的数据写入 avalon 从站。我已经验证我能够通过使用一些硬编码值从从站读取数据。我还验证了我的应用程序正在运行,因为我在 jtag uart 上看到了我期望的消息,并且按钮、LED 和 LED 显示屏按预期工作。

我已经简化了我的奴隶,以便我写入它的数据可以直接读回。 VHDL代码为:

library ieee;
use ieee.std_logic_1164.all;
USE IEEE.NUMERIC_STD.ALL;

entity FIFO_Control is
    port (clk : IN std_logic; 
            reset : IN std_logic;
            read : IN std_logic; 
            readdata : OUT std_logic_vector(7 DOWNTO 0); 
            write : IN std_logic; 
            writedata : IN std_logic_vector(7 DOWNTO 0);
            din1 : in std_logic_vector(4 DOWNTO 0);
            din2 : in std_logic_vector(4 DOWNTO 0)
            );
end FIFO_Control;


architecture FIFO_CTRL of FIFO_Control is

    signal int_data : std_logic_vector(7 DOWNTO 0) := "00000000"; -- a hard coded test value to check the read works

    begin
        with (write) SELECT
            int_data <= writedata when '1',
                            "01010101" when others;

            readdata <= int_data;


end FIFO_CTRL;

C 代码是

#include "sys/alt_stdio.h"
#include <altera_avalon_timer_regs.h>
#include <altera_avalon_pio_regs.h>
#include <system.h>

#include "Sch51.h"

#include "serial.h"

#include "seven_seg.h"

#define SEVEN_SEGMENT_0_BASE 0x1001080
#define LED_BASE (0x01001070)
#define LED0_pin (0x01)
#define LED1_pin (0x01 << 1)
#define LED2_pin (0x01 << 2)
#define LED3_pin (0x01 << 3)

#define PIO_1_BASE 0x0
#define BUTTON_BASE PIO_1_BASE
#define BUTTON0 0x01
#define BUTTON1 0x02

#define FIFO_CTRL_0_BASE 0x1001090

void LED_Flash_Update(void)
{
    static count = 0;
    alt_u8 read;

    IOWR_8DIRECT(FIFO_CTRL_0_BASE, 0, 0);
    read = IORD_8DIRECT(FIFO_CTRL_0_BASE, 0);
    Serial_Printf("FIFO1: %d\r\n", read);

    IOWR_8DIRECT(FIFO_CTRL_0_BASE, 0, 1);
    read = IORD_8DIRECT(FIFO_CTRL_0_BASE, 0);
    Serial_Printf("FIFO1: %d\r\n", read);

   // Change the LED from OFF to ON (or vice versa)
   IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,
         IORD_ALTERA_AVALON_PIO_DATA(LED_BASE) ^ LED3_pin);

   if (count < 10)
   {
       count++;
   }

   else if ((count >= 10) && (count < 100))
   {
       count += 10;
   }

   else if ((count >= 100) && (count < 1000))
   {
     count += 100;
   }

   else if ((count >= 1000) && (count < 10000))
   {
     count += 1000;
   }

   else
   {
       count = 0;
   }

   seven_seg_store_number(SEVEN_SEGMENT_0_BASE, 0, 9999, 10, count);

   if ((IORD_ALTERA_AVALON_PIO_DATA(BUTTON_BASE) & BUTTON0) == 0)
   {
       IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,
                IORD_ALTERA_AVALON_PIO_DATA(LED_BASE) | LED0_pin);
   }

   else
   {
       IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,
                    IORD_ALTERA_AVALON_PIO_DATA(LED_BASE) & ~LED0_pin);
   }

   if ((IORD_ALTERA_AVALON_PIO_DATA(BUTTON_BASE) & BUTTON1) == 0)
   {
       IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,
                IORD_ALTERA_AVALON_PIO_DATA(LED_BASE) | LED1_pin);
   }

   else
   {
       IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,
                    IORD_ALTERA_AVALON_PIO_DATA(LED_BASE) &  ~LED1_pin);
   }

}

int alt_main()
{
    alt_u8 read;
    SCH_Init_T0();
    serial_Init();

    SCH_Add_Task(serial_Update, 0, 10);
    SCH_Add_Task(LED_Flash_Update, 0, 1000);

    // Start the scheduler
    SCH_Start();

    Serial_Puts("EHMC AJE System Running\n");

    /* Event loop never exits. */
    while (1)
    {
        SCH_Dispatch_Tasks();
    }

    return 0;
}

我不明白为什么我无法向 avalon 从站“Fifo_control”写入任何内容。有人可以提出问题是什么吗?

【问题讨论】:

  • readwrite 输入是什么?他们控制频闪,你知道他们是如何工作的吗?先画一个时序图。您的代码似乎没有做任何有用的事情 - 它只是在 write 为 1 时将 writedata 路由回 readdata,这几乎肯定不是您想要的。请不要在 VHDL 问题中使用 C 代码。
  • @EML c 代码端通常对这类接口(Avalon、AXi、wishbone)很重要,所以我不同意你最后的说法。

标签: vhdl fpga intel-fpga nios


【解决方案1】:

如果您查看实体/组件上的端口声明,然后查看代码,您已经可以看到您做错了什么,因为您没有使用所有端口。

所以您的问题表明您想将数据写入您的 Avalon 从站。因此,您希望组件记住您写入的数据(即内存)。但是您的代码中没有内存组件。这只是一个组合表达式。

在设计 Avalon 组件时,您应该阅读Avalon Interface Specification

所以阅读文档,您会看到您应该有一个用于写入端口的进程/语句和一个用于读取端口的进程。每个都需要一个时钟周期来处理(如果读取延迟为 1)。例如

write_proc: process(clk) begin
    if rising_edge(clk) then
        if write = '1' then
            int_data <= writedata;
        end if;
        -- reset statement
        if reset = '1' then
            int_data <= (others => '0');
        end if;
    end if;
end process;

read_proc: process(clk) begin
    if rising_edge(clk) then
        if read = '1' then
            readdata <= int_data;
        end if;
        -- reset statement
        if reset = '1' then
            readdata <= (others => '0');
        end if;
    end if;
end process;

【讨论】:

  • 您好 JHBonarius 感谢您的回复和洞察力,您的回答非常清晰和有帮助。我知道有一个工作界面。也感谢您对 C 代码的回复。我也发布了,因为我不确定我的问题到底出在哪里。所以我把 VHDL 和 C 都贴出来了,这样界面的两边都可以看到。
猜你喜欢
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 2015-09-26
  • 2013-12-19
相关资源
最近更新 更多