mirror of
https://github.com/fpganinja/taxi.git
synced 2026-04-09 05:18:44 -07:00
Compare commits
10 Commits
f8f73ea570
...
ce8da1bc59
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce8da1bc59 | ||
|
|
d0c9ae0637 | ||
|
|
a46b012c91 | ||
|
|
595d744aa4 | ||
|
|
8263ebab24 | ||
|
|
7dbe6df56a | ||
|
|
8f1c082174 | ||
|
|
39c9dce0fa | ||
|
|
f8764d581d | ||
|
|
cce4c4525e |
@@ -136,6 +136,9 @@ struct cndm_cq {
|
|||||||
struct cndm_ring *src_ring;
|
struct cndm_ring *src_ring;
|
||||||
|
|
||||||
void (*handler)(struct cndm_cq *cq);
|
void (*handler)(struct cndm_cq *cq);
|
||||||
|
|
||||||
|
u32 db_offset;
|
||||||
|
u8 __iomem *db_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cndm_priv {
|
struct cndm_priv {
|
||||||
@@ -157,9 +160,7 @@ struct cndm_priv {
|
|||||||
int txq_count;
|
int txq_count;
|
||||||
|
|
||||||
struct cndm_ring *txq;
|
struct cndm_ring *txq;
|
||||||
struct cndm_cq *txcq;
|
|
||||||
struct cndm_ring *rxq;
|
struct cndm_ring *rxq;
|
||||||
struct cndm_cq *rxcq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// cndm_cmd.c
|
// cndm_cmd.c
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ struct cndm_cq *cndm_create_cq(struct cndm_priv *priv)
|
|||||||
|
|
||||||
cq->cons_ptr = 0;
|
cq->cons_ptr = 0;
|
||||||
|
|
||||||
|
cq->db_offset = 0;
|
||||||
|
cq->db_addr = NULL;
|
||||||
|
|
||||||
return cq;
|
return cq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +77,20 @@ int cndm_open_cq(struct cndm_cq *cq, int irqn, int size)
|
|||||||
|
|
||||||
cndm_exec_cmd(cq->cdev, &cmd, &rsp);
|
cndm_exec_cmd(cq->cdev, &cmd, &rsp);
|
||||||
|
|
||||||
|
if (rsp.dboffs == 0) {
|
||||||
|
netdev_err(cq->priv->ndev, "Failed to allocate CQ");
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
cq->cqn = rsp.qn;
|
cq->cqn = rsp.qn;
|
||||||
|
cq->db_offset = rsp.dboffs;
|
||||||
|
cq->db_addr = cq->cdev->hw_addr + rsp.dboffs;
|
||||||
|
|
||||||
cq->enabled = 1;
|
cq->enabled = 1;
|
||||||
|
|
||||||
|
netdev_dbg(cq->priv->ndev, "Opened CQ %d", cq->cqn);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -102,6 +115,8 @@ void cndm_close_cq(struct cndm_cq *cq)
|
|||||||
cndm_exec_cmd(cdev, &cmd, &rsp);
|
cndm_exec_cmd(cdev, &cmd, &rsp);
|
||||||
|
|
||||||
cq->cqn = -1;
|
cq->cqn = -1;
|
||||||
|
cq->db_offset = 0;
|
||||||
|
cq->db_addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cq->buf) {
|
if (cq->buf) {
|
||||||
|
|||||||
@@ -9,54 +9,168 @@ Authors:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cndm.h"
|
#include "cndm.h"
|
||||||
#include "cndm_hw.h"
|
|
||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
static int cndm_close(struct net_device *ndev);
|
||||||
|
|
||||||
static int cndm_open(struct net_device *ndev)
|
static int cndm_open(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct cndm_priv *priv = netdev_priv(ndev);
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
struct cndm_ring *q;
|
||||||
|
struct cndm_cq *cq;
|
||||||
|
int k;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
cndm_refill_rx_buffers(priv->rxq);
|
netdev_info(ndev, "Open port");
|
||||||
|
|
||||||
priv->txq->tx_queue = netdev_get_tx_queue(ndev, 0);
|
netif_set_real_num_tx_queues(ndev, priv->txq_count);
|
||||||
|
netif_set_real_num_rx_queues(ndev, priv->rxq_count);
|
||||||
|
|
||||||
netif_napi_add_tx(ndev, &priv->txcq->napi, cndm_poll_tx_cq);
|
// set up RX queues
|
||||||
napi_enable(&priv->txcq->napi);
|
for (k = 0; k < priv->rxq_count; k++) {
|
||||||
netif_napi_add(ndev, &priv->rxcq->napi, cndm_poll_rx_cq);
|
if (priv->rxq)
|
||||||
napi_enable(&priv->rxcq->napi);
|
break;
|
||||||
|
|
||||||
|
cq = cndm_create_cq(priv);
|
||||||
|
if (IS_ERR_OR_NULL(cq)) {
|
||||||
|
ret = PTR_ERR(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cndm_open_cq(cq, 0, 256);
|
||||||
|
if (ret) {
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
q = cndm_create_rq(priv);
|
||||||
|
if (IS_ERR_OR_NULL(q)) {
|
||||||
|
ret = PTR_ERR(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cndm_open_rq(q, priv, cq, 256);
|
||||||
|
if (ret) {
|
||||||
|
cndm_destroy_rq(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->rxq = q;
|
||||||
|
|
||||||
|
netif_napi_add(ndev, &cq->napi, cndm_poll_rx_cq);
|
||||||
|
napi_enable(&cq->napi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up TX queues
|
||||||
|
for (k = 0; k < priv->txq_count; k++) {
|
||||||
|
if (priv->txq)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cq = cndm_create_cq(priv);
|
||||||
|
if (IS_ERR_OR_NULL(cq)) {
|
||||||
|
ret = PTR_ERR(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cndm_open_cq(cq, 0, 256);
|
||||||
|
if (ret) {
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
q = cndm_create_sq(priv);
|
||||||
|
if (IS_ERR_OR_NULL(q)) {
|
||||||
|
ret = PTR_ERR(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->tx_queue = netdev_get_tx_queue(ndev, k);
|
||||||
|
|
||||||
|
ret = cndm_open_sq(q, priv, cq, 256);
|
||||||
|
if (ret) {
|
||||||
|
cndm_destroy_sq(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->txq = q;
|
||||||
|
|
||||||
|
netif_napi_add_tx(ndev, &cq->napi, cndm_poll_tx_cq);
|
||||||
|
napi_enable(&cq->napi);
|
||||||
|
}
|
||||||
|
|
||||||
netif_tx_start_all_queues(ndev);
|
netif_tx_start_all_queues(ndev);
|
||||||
netif_carrier_on(ndev);
|
|
||||||
netif_device_attach(ndev);
|
netif_device_attach(ndev);
|
||||||
|
netif_carrier_on(ndev);
|
||||||
|
|
||||||
priv->port_up = 1;
|
priv->port_up = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
cndm_close(ndev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cndm_close(struct net_device *ndev)
|
static int cndm_close(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct cndm_priv *priv = netdev_priv(ndev);
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
struct cndm_ring *q;
|
||||||
|
struct cndm_cq *cq;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
netdev_info(ndev, "Close port");
|
||||||
|
|
||||||
if (!priv->port_up)
|
if (!priv->port_up)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
priv->port_up = 0;
|
netif_tx_lock_bh(ndev);
|
||||||
|
|
||||||
if (priv->txcq) {
|
|
||||||
napi_disable(&priv->txcq->napi);
|
|
||||||
netif_napi_del(&priv->txcq->napi);
|
|
||||||
}
|
|
||||||
if (priv->rxcq) {
|
|
||||||
napi_disable(&priv->rxcq->napi);
|
|
||||||
netif_napi_del(&priv->rxcq->napi);
|
|
||||||
}
|
|
||||||
|
|
||||||
netif_tx_stop_all_queues(ndev);
|
netif_tx_stop_all_queues(ndev);
|
||||||
|
netif_tx_unlock_bh(ndev);
|
||||||
|
|
||||||
netif_carrier_off(ndev);
|
netif_carrier_off(ndev);
|
||||||
netif_tx_disable(ndev);
|
netif_tx_disable(ndev);
|
||||||
|
|
||||||
|
priv->port_up = 0;
|
||||||
|
|
||||||
|
// clean up TX queues
|
||||||
|
for (k = 0; k < priv->txq_count; k++) {
|
||||||
|
if (!priv->txq)
|
||||||
|
break;
|
||||||
|
|
||||||
|
q = priv->txq;
|
||||||
|
cq = q->cq;
|
||||||
|
|
||||||
|
napi_disable(&cq->napi);
|
||||||
|
netif_napi_del(&cq->napi);
|
||||||
|
|
||||||
|
cndm_destroy_sq(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
|
||||||
|
priv->txq = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up RX queues
|
||||||
|
for (k = 0; k < priv->rxq_count; k++) {
|
||||||
|
if (!priv->rxq)
|
||||||
|
break;
|
||||||
|
|
||||||
|
q = priv->rxq;
|
||||||
|
cq = q->cq;
|
||||||
|
|
||||||
|
napi_disable(&cq->napi);
|
||||||
|
netif_napi_del(&cq->napi);
|
||||||
|
|
||||||
|
cndm_destroy_rq(q);
|
||||||
|
cndm_destroy_cq(cq);
|
||||||
|
|
||||||
|
priv->rxq = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,8 +285,8 @@ static int cndm_netdev_irq(struct notifier_block *nb, unsigned long action, void
|
|||||||
netdev_dbg(priv->ndev, "Interrupt");
|
netdev_dbg(priv->ndev, "Interrupt");
|
||||||
|
|
||||||
if (priv->port_up) {
|
if (priv->port_up) {
|
||||||
napi_schedule_irqoff(&priv->txcq->napi);
|
napi_schedule_irqoff(&priv->txq->cq->napi);
|
||||||
napi_schedule_irqoff(&priv->rxcq->napi);
|
napi_schedule_irqoff(&priv->rxq->cq->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
@@ -226,54 +340,6 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port)
|
|||||||
ndev->min_mtu = ETH_MIN_MTU;
|
ndev->min_mtu = ETH_MIN_MTU;
|
||||||
ndev->max_mtu = 1500;
|
ndev->max_mtu = 1500;
|
||||||
|
|
||||||
priv->rxcq = cndm_create_cq(priv);
|
|
||||||
if (IS_ERR_OR_NULL(priv->rxcq)) {
|
|
||||||
ret = PTR_ERR(priv->rxcq);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = cndm_open_cq(priv->rxcq, 0, 256);
|
|
||||||
if (ret) {
|
|
||||||
cndm_destroy_cq(priv->rxcq);
|
|
||||||
priv->rxcq = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->rxq = cndm_create_rq(priv);
|
|
||||||
if (IS_ERR_OR_NULL(priv->rxq)) {
|
|
||||||
ret = PTR_ERR(priv->rxq);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = cndm_open_rq(priv->rxq, priv, priv->rxcq, 256);
|
|
||||||
if (ret) {
|
|
||||||
cndm_destroy_rq(priv->rxq);
|
|
||||||
priv->rxq = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->txcq = cndm_create_cq(priv);
|
|
||||||
if (IS_ERR_OR_NULL(priv->txcq)) {
|
|
||||||
ret = PTR_ERR(priv->txcq);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = cndm_open_cq(priv->txcq, 0, 256);
|
|
||||||
if (ret) {
|
|
||||||
cndm_destroy_cq(priv->txcq);
|
|
||||||
priv->txcq = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->txq = cndm_create_sq(priv);
|
|
||||||
if (IS_ERR_OR_NULL(priv->txq)) {
|
|
||||||
ret = PTR_ERR(priv->txq);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = cndm_open_sq(priv->txq, priv, priv->txcq, 256);
|
|
||||||
if (ret) {
|
|
||||||
cndm_destroy_sq(priv->txq);
|
|
||||||
priv->txq = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
netif_carrier_off(ndev);
|
netif_carrier_off(ndev);
|
||||||
|
|
||||||
ret = register_netdev(ndev);
|
ret = register_netdev(ndev);
|
||||||
@@ -292,7 +358,6 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ndev;
|
return ndev;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -304,40 +369,13 @@ void cndm_destroy_netdev(struct net_device *ndev)
|
|||||||
{
|
{
|
||||||
struct cndm_priv *priv = netdev_priv(ndev);
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
|
||||||
if (priv->port_up)
|
if (priv->registered)
|
||||||
cndm_close(ndev);
|
unregister_netdev(ndev);
|
||||||
|
|
||||||
if (priv->txq) {
|
|
||||||
cndm_close_sq(priv->txq);
|
|
||||||
cndm_destroy_sq(priv->txq);
|
|
||||||
priv->txq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->txcq) {
|
|
||||||
cndm_close_cq(priv->txcq);
|
|
||||||
cndm_destroy_cq(priv->txcq);
|
|
||||||
priv->txcq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rxq) {
|
|
||||||
cndm_close_rq(priv->rxq);
|
|
||||||
cndm_destroy_rq(priv->rxq);
|
|
||||||
priv->rxq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rxcq) {
|
|
||||||
cndm_close_cq(priv->rxcq);
|
|
||||||
cndm_destroy_cq(priv->rxcq);
|
|
||||||
priv->rxcq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->irq)
|
if (priv->irq)
|
||||||
atomic_notifier_chain_unregister(&priv->irq->nh, &priv->irq_nb);
|
atomic_notifier_chain_unregister(&priv->irq->nh, &priv->irq_nb);
|
||||||
|
|
||||||
priv->irq = NULL;
|
priv->irq = NULL;
|
||||||
|
|
||||||
if (priv->registered)
|
|
||||||
unregister_netdev(ndev);
|
|
||||||
|
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,12 +87,20 @@ int cndm_open_rq(struct cndm_ring *rq, struct cndm_priv *priv, struct cndm_cq *c
|
|||||||
|
|
||||||
cndm_exec_cmd(rq->cdev, &cmd, &rsp);
|
cndm_exec_cmd(rq->cdev, &cmd, &rsp);
|
||||||
|
|
||||||
|
if (rsp.dboffs == 0) {
|
||||||
|
netdev_err(rq->priv->ndev, "Failed to allocate RQ");
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
rq->index = rsp.qn;
|
rq->index = rsp.qn;
|
||||||
rq->db_offset = rsp.dboffs;
|
rq->db_offset = rsp.dboffs;
|
||||||
rq->db_addr = priv->cdev->hw_addr + rsp.dboffs;
|
rq->db_addr = rq->cdev->hw_addr + rsp.dboffs;
|
||||||
|
|
||||||
rq->enabled = 1;
|
rq->enabled = 1;
|
||||||
|
|
||||||
|
netdev_dbg(cq->priv->ndev, "Opened RQ %d (CQ %d)", rq->index, cq->cqn);
|
||||||
|
|
||||||
ret = cndm_refill_rx_buffers(rq);
|
ret = cndm_refill_rx_buffers(rq);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
netdev_err(priv->ndev, "failed to allocate RX buffer for RX queue index %d (of %u total) entry index %u (of %u total)",
|
netdev_err(priv->ndev, "failed to allocate RX buffer for RX queue index %d (of %u total) entry index %u (of %u total)",
|
||||||
@@ -135,6 +143,8 @@ void cndm_close_rq(struct cndm_ring *rq)
|
|||||||
cndm_exec_cmd(cdev, &cmd, &rsp);
|
cndm_exec_cmd(cdev, &cmd, &rsp);
|
||||||
|
|
||||||
rq->index = -1;
|
rq->index = -1;
|
||||||
|
rq->db_offset = 0;
|
||||||
|
rq->db_addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rq->buf) {
|
if (rq->buf) {
|
||||||
|
|||||||
@@ -87,12 +87,20 @@ int cndm_open_sq(struct cndm_ring *sq, struct cndm_priv *priv, struct cndm_cq *c
|
|||||||
|
|
||||||
cndm_exec_cmd(sq->cdev, &cmd, &rsp);
|
cndm_exec_cmd(sq->cdev, &cmd, &rsp);
|
||||||
|
|
||||||
|
if (rsp.dboffs == 0) {
|
||||||
|
netdev_err(sq->priv->ndev, "Failed to allocate SQ");
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
sq->index = rsp.qn;
|
sq->index = rsp.qn;
|
||||||
sq->db_offset = rsp.dboffs;
|
sq->db_offset = rsp.dboffs;
|
||||||
sq->db_addr = priv->cdev->hw_addr + rsp.dboffs;
|
sq->db_addr = sq->cdev->hw_addr + rsp.dboffs;
|
||||||
|
|
||||||
sq->enabled = 1;
|
sq->enabled = 1;
|
||||||
|
|
||||||
|
netdev_dbg(cq->priv->ndev, "Opened SQ %d (CQ %d)", sq->index, cq->cqn);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -124,6 +132,8 @@ void cndm_close_sq(struct cndm_ring *sq)
|
|||||||
cndm_exec_cmd(cdev, &cmd, &rsp);
|
cndm_exec_cmd(cdev, &cmd, &rsp);
|
||||||
|
|
||||||
sq->index = -1;
|
sq->index = -1;
|
||||||
|
sq->db_offset = 0;
|
||||||
|
sq->db_addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sq->buf) {
|
if (sq->buf) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ cndm_micro_dp_mgr.sv
|
|||||||
cndm_micro_port.sv
|
cndm_micro_port.sv
|
||||||
cndm_micro_rx.sv
|
cndm_micro_rx.sv
|
||||||
cndm_micro_tx.sv
|
cndm_micro_tx.sv
|
||||||
|
cndm_micro_queue_state.sv
|
||||||
cndm_micro_desc_rd.sv
|
cndm_micro_desc_rd.sv
|
||||||
cndm_micro_cpl_wr.sv
|
cndm_micro_cpl_wr.sv
|
||||||
../lib/taxi/src/prim/rtl/taxi_ram_2rw_1c.sv
|
../lib/taxi/src/prim/rtl/taxi_ram_2rw_1c.sv
|
||||||
@@ -14,7 +15,7 @@ cndm_micro_cpl_wr.sv
|
|||||||
../lib/taxi/src/apb/rtl/taxi_apb_if.sv
|
../lib/taxi/src/apb/rtl/taxi_apb_if.sv
|
||||||
../lib/taxi/src/apb/rtl/taxi_apb_interconnect.sv
|
../lib/taxi/src/apb/rtl/taxi_apb_interconnect.sv
|
||||||
../lib/taxi/src/axi/rtl/taxi_axil_interconnect_1s.f
|
../lib/taxi/src/axi/rtl/taxi_axil_interconnect_1s.f
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_async_fifo.f
|
../lib/taxi/src/axis/rtl/taxi_axis_async_fifo_adapter.f
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_arb_mux.f
|
../lib/taxi/src/axis/rtl/taxi_axis_arb_mux.f
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_demux.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_demux.sv
|
||||||
../lib/taxi/src/ptp/rtl/taxi_ptp_td_phc_apb.f
|
../lib/taxi/src/ptp/rtl/taxi_ptp_td_phc_apb.f
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ module cndm_micro_core #(
|
|||||||
// Structural configuration
|
// Structural configuration
|
||||||
parameter PORTS = 2,
|
parameter PORTS = 2,
|
||||||
|
|
||||||
|
// Queue configuration
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
parameter CQN_W = WQN_W,
|
||||||
|
|
||||||
// PTP configuration
|
// PTP configuration
|
||||||
parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
||||||
@@ -300,16 +304,23 @@ cmd_mbox_inst (
|
|||||||
|
|
||||||
// datapath manager
|
// datapath manager
|
||||||
|
|
||||||
|
localparam APB_DP_ADDR_W = 16+$clog2(PORTS+PORT_OFFSET_DP);
|
||||||
|
|
||||||
taxi_apb_if #(
|
taxi_apb_if #(
|
||||||
.DATA_W(32),
|
.DATA_W(32),
|
||||||
.ADDR_W(16+$clog2(PORTS+PORT_OFFSET_DP))
|
.ADDR_W(APB_DP_ADDR_W)
|
||||||
)
|
)
|
||||||
apb_dp_ctrl();
|
apb_dp_ctrl();
|
||||||
|
|
||||||
cndm_micro_dp_mgr #(
|
cndm_micro_dp_mgr #(
|
||||||
.PORTS(PORTS),
|
.PORTS(PORTS),
|
||||||
|
|
||||||
|
.WQN_W(WQN_W),
|
||||||
|
.CQN_W(CQN_W),
|
||||||
|
|
||||||
.PTP_EN(PTP_TS_EN),
|
.PTP_EN(PTP_TS_EN),
|
||||||
.PTP_BASE_ADDR_DP(0),
|
.PTP_BASE_ADDR_DP(0),
|
||||||
|
|
||||||
.PORT_BASE_ADDR_DP(PORT_BASE_ADDR_DP),
|
.PORT_BASE_ADDR_DP(PORT_BASE_ADDR_DP),
|
||||||
.PORT_BASE_ADDR_HOST(PORT_BASE_ADDR_HOST)
|
.PORT_BASE_ADDR_HOST(PORT_BASE_ADDR_HOST)
|
||||||
)
|
)
|
||||||
@@ -337,7 +348,7 @@ apb_port_dp_ctrl[PORT_OFFSET_DP+PORTS]();
|
|||||||
|
|
||||||
taxi_apb_interconnect #(
|
taxi_apb_interconnect #(
|
||||||
.M_CNT($size(apb_port_dp_ctrl)),
|
.M_CNT($size(apb_port_dp_ctrl)),
|
||||||
.ADDR_W(apb_dp_ctrl.ADDR_W),
|
.ADDR_W(APB_DP_ADDR_W),
|
||||||
.M_REGIONS(1),
|
.M_REGIONS(1),
|
||||||
.M_BASE_ADDR('0),
|
.M_BASE_ADDR('0),
|
||||||
.M_ADDR_W({$size(apb_port_dp_ctrl){{1{32'd16}}}}),
|
.M_ADDR_W({$size(apb_port_dp_ctrl){{1{32'd16}}}}),
|
||||||
@@ -490,6 +501,11 @@ dma_mux_inst (
|
|||||||
for (genvar p = 0; p < PORTS; p = p + 1) begin : port
|
for (genvar p = 0; p < PORTS; p = p + 1) begin : port
|
||||||
|
|
||||||
cndm_micro_port #(
|
cndm_micro_port #(
|
||||||
|
// Queue configuration
|
||||||
|
.WQN_W(WQN_W),
|
||||||
|
.CQN_W(CQN_W),
|
||||||
|
|
||||||
|
// PTP configuration
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (c) 2025 FPGA Ninja, LLC
|
Copyright (c) 2026 FPGA Ninja, LLC
|
||||||
|
|
||||||
Authors:
|
Authors:
|
||||||
- Alex Forencich
|
- Alex Forencich
|
||||||
@@ -15,7 +15,9 @@ Authors:
|
|||||||
/*
|
/*
|
||||||
* Corundum-micro completion write module
|
* Corundum-micro completion write module
|
||||||
*/
|
*/
|
||||||
module cndm_micro_cpl_wr
|
module cndm_micro_cpl_wr #(
|
||||||
|
parameter CQN_W = 5
|
||||||
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
@@ -42,168 +44,59 @@ module cndm_micro_cpl_wr
|
|||||||
output wire logic irq
|
output wire logic irq
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
|
localparam DMA_ADDR_W = dma_wr_desc_req.DST_ADDR_W;
|
||||||
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
|
|
||||||
|
|
||||||
localparam APB_ADDR_W = s_apb_dp_ctrl.ADDR_W;
|
logic [CQN_W-1:0] cq_req_cqn_reg = '0;
|
||||||
localparam APB_DATA_W = s_apb_dp_ctrl.DATA_W;
|
logic cq_req_valid_reg = 1'b0;
|
||||||
|
logic cq_req_ready;
|
||||||
|
logic [DMA_ADDR_W-1:0] cq_rsp_addr;
|
||||||
|
logic cq_rsp_phase_tag;
|
||||||
|
logic cq_rsp_error;
|
||||||
|
logic cq_rsp_valid;
|
||||||
|
logic cq_rsp_ready_reg = 1'b0;
|
||||||
|
|
||||||
logic txcq_en_reg = '0;
|
cndm_micro_queue_state #(
|
||||||
logic [3:0] txcq_size_reg = '0;
|
.QN_W(CQN_W),
|
||||||
logic [63:0] txcq_base_addr_reg = '0;
|
.DQN_W(CQN_W), // TODO
|
||||||
logic rxcq_en_reg = '0;
|
.IS_CQ(1),
|
||||||
logic [3:0] rxcq_size_reg = '0;
|
.QTYPE_EN(0),
|
||||||
logic [63:0] rxcq_base_addr_reg = '0;
|
.QE_SIZE(16),
|
||||||
|
.DMA_ADDR_W(DMA_ADDR_W)
|
||||||
|
)
|
||||||
|
cq_mgr_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
logic [15:0] txcq_prod_ptr_reg = '0;
|
/*
|
||||||
logic [15:0] rxcq_prod_ptr_reg = '0;
|
* Control register interface
|
||||||
|
*/
|
||||||
|
.s_axil_ctrl_wr(s_axil_ctrl_wr),
|
||||||
|
.s_axil_ctrl_rd(s_axil_ctrl_rd),
|
||||||
|
|
||||||
logic s_axil_ctrl_awready_reg = 1'b0;
|
/*
|
||||||
logic s_axil_ctrl_wready_reg = 1'b0;
|
* Datapath control register interface
|
||||||
logic s_axil_ctrl_bvalid_reg = 1'b0;
|
*/
|
||||||
|
.s_apb_dp_ctrl(s_apb_dp_ctrl),
|
||||||
|
|
||||||
logic s_axil_ctrl_arready_reg = 1'b0;
|
/*
|
||||||
logic [AXIL_DATA_W-1:0] s_axil_ctrl_rdata_reg = '0;
|
* Queue management interface
|
||||||
logic s_axil_ctrl_rvalid_reg = 1'b0;
|
*/
|
||||||
|
.req_qn(cq_req_cqn_reg),
|
||||||
assign s_axil_ctrl_wr.awready = s_axil_ctrl_awready_reg;
|
.req_qtype('0),
|
||||||
assign s_axil_ctrl_wr.wready = s_axil_ctrl_wready_reg;
|
.req_valid(cq_req_valid_reg),
|
||||||
assign s_axil_ctrl_wr.bresp = '0;
|
.req_ready(cq_req_ready),
|
||||||
assign s_axil_ctrl_wr.buser = '0;
|
.rsp_qn(),
|
||||||
assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg;
|
.rsp_dqn(),
|
||||||
|
.rsp_addr(cq_rsp_addr),
|
||||||
assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg;
|
.rsp_phase_tag(cq_rsp_phase_tag),
|
||||||
assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg;
|
.rsp_error(cq_rsp_error),
|
||||||
assign s_axil_ctrl_rd.rresp = '0;
|
.rsp_valid(cq_rsp_valid),
|
||||||
assign s_axil_ctrl_rd.ruser = '0;
|
.rsp_ready(cq_rsp_ready_reg)
|
||||||
assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg;
|
);
|
||||||
|
|
||||||
logic s_apb_dp_ctrl_pready_reg = 1'b0;
|
|
||||||
logic [AXIL_DATA_W-1:0] s_apb_dp_ctrl_prdata_reg = '0;
|
|
||||||
|
|
||||||
assign s_apb_dp_ctrl.pready = s_apb_dp_ctrl_pready_reg;
|
|
||||||
assign s_apb_dp_ctrl.prdata = s_apb_dp_ctrl_prdata_reg;
|
|
||||||
assign s_apb_dp_ctrl.pslverr = 1'b0;
|
|
||||||
assign s_apb_dp_ctrl.pruser = '0;
|
|
||||||
assign s_apb_dp_ctrl.pbuser = '0;
|
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_bvalid_reg <= s_axil_ctrl_bvalid_reg && !s_axil_ctrl_wr.bready;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_rvalid_reg <= s_axil_ctrl_rvalid_reg && !s_axil_ctrl_rd.rready;
|
|
||||||
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b0;
|
|
||||||
|
|
||||||
if (s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_bvalid_reg <= 1'b1;
|
|
||||||
|
|
||||||
// case ({s_axil_ctrl_wr.awaddr[9:2], 2'b00})
|
|
||||||
// 10'h000: begin
|
|
||||||
// txcq_en_reg <= s_axil_ctrl_wr.wdata[0];
|
|
||||||
// txcq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
|
|
||||||
// end
|
|
||||||
// 10'h008: txcq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
|
|
||||||
// 10'h00c: txcq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
|
|
||||||
|
|
||||||
// 10'h100: begin
|
|
||||||
// rxcq_en_reg <= s_axil_ctrl_wr.wdata[0];
|
|
||||||
// rxcq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
|
|
||||||
// end
|
|
||||||
// 10'h108: rxcq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
|
|
||||||
// 10'h10c: rxcq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
|
|
||||||
// default: begin end
|
|
||||||
// endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (s_axil_ctrl_rd.arvalid && !s_axil_ctrl_rvalid_reg) begin
|
|
||||||
s_axil_ctrl_rdata_reg <= '0;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_rvalid_reg <= 1'b1;
|
|
||||||
|
|
||||||
// case ({s_axil_ctrl_rd.araddr[9:2], 2'b00})
|
|
||||||
// 10'h000: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[0] <= txcq_en_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[19:16] <= txcq_size_reg;
|
|
||||||
// end
|
|
||||||
// 10'h004: s_axil_ctrl_rdata_reg[15:0] <= txcq_prod_ptr_reg;
|
|
||||||
// 10'h008: s_axil_ctrl_rdata_reg <= txcq_base_addr_reg[31:0];
|
|
||||||
// 10'h00c: s_axil_ctrl_rdata_reg <= txcq_base_addr_reg[63:32];
|
|
||||||
|
|
||||||
// 10'h100: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[0] <= rxcq_en_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[19:16] <= rxcq_size_reg;
|
|
||||||
// end
|
|
||||||
// 10'h104: s_axil_ctrl_rdata_reg[15:0] <= rxcq_prod_ptr_reg;
|
|
||||||
// 10'h108: s_axil_ctrl_rdata_reg <= rxcq_base_addr_reg[31:0];
|
|
||||||
// 10'h10c: s_axil_ctrl_rdata_reg <= rxcq_base_addr_reg[63:32];
|
|
||||||
// default: begin end
|
|
||||||
// endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b1;
|
|
||||||
s_apb_dp_ctrl_prdata_reg <= '0;
|
|
||||||
|
|
||||||
if (s_apb_dp_ctrl.pwrite) begin
|
|
||||||
case ({s_apb_dp_ctrl.paddr[9:2], 2'b00})
|
|
||||||
10'h000: begin
|
|
||||||
txcq_en_reg <= s_apb_dp_ctrl.pwdata[0];
|
|
||||||
txcq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
|
|
||||||
end
|
|
||||||
10'h008: txcq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
10'h00c: txcq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
|
|
||||||
10'h100: begin
|
|
||||||
rxcq_en_reg <= s_apb_dp_ctrl.pwdata[0];
|
|
||||||
rxcq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
|
|
||||||
end
|
|
||||||
10'h108: rxcq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
10'h10c: rxcq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
case ({s_apb_dp_ctrl.paddr[9:2], 2'b00})
|
|
||||||
10'h000: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[0] <= txcq_en_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[19:16] <= txcq_size_reg;
|
|
||||||
end
|
|
||||||
10'h004: s_apb_dp_ctrl_prdata_reg[15:0] <= txcq_prod_ptr_reg;
|
|
||||||
10'h008: s_apb_dp_ctrl_prdata_reg <= txcq_base_addr_reg[31:0];
|
|
||||||
10'h00c: s_apb_dp_ctrl_prdata_reg <= txcq_base_addr_reg[63:32];
|
|
||||||
|
|
||||||
10'h100: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[0] <= rxcq_en_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[19:16] <= rxcq_size_reg;
|
|
||||||
end
|
|
||||||
10'h104: s_apb_dp_ctrl_prdata_reg[15:0] <= rxcq_prod_ptr_reg;
|
|
||||||
10'h108: s_apb_dp_ctrl_prdata_reg <= rxcq_base_addr_reg[31:0];
|
|
||||||
10'h10c: s_apb_dp_ctrl_prdata_reg <= rxcq_base_addr_reg[63:32];
|
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (rst) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_bvalid_reg <= 1'b0;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_rvalid_reg <= 1'b0;
|
|
||||||
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
STATE_RX_CPL,
|
STATE_QUERY_CQ,
|
||||||
STATE_WRITE_DATA
|
STATE_WRITE_DATA
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
@@ -231,13 +124,8 @@ always_ff @(posedge clk) begin
|
|||||||
dma_wr_desc_req.req_user <= '0;
|
dma_wr_desc_req.req_user <= '0;
|
||||||
dma_wr_desc_req.req_valid <= dma_wr_desc_req.req_valid && !dma_wr_desc_req.req_ready;
|
dma_wr_desc_req.req_valid <= dma_wr_desc_req.req_valid && !dma_wr_desc_req.req_ready;
|
||||||
|
|
||||||
if (!txcq_en_reg) begin
|
cq_req_valid_reg <= cq_req_valid_reg && !cq_req_ready;
|
||||||
txcq_prod_ptr_reg <= '0;
|
cq_rsp_ready_reg <= 1'b0;
|
||||||
end
|
|
||||||
|
|
||||||
if (!rxcq_en_reg) begin
|
|
||||||
rxcq_prod_ptr_reg <= '0;
|
|
||||||
end
|
|
||||||
|
|
||||||
irq_reg <= 1'b0;
|
irq_reg <= 1'b0;
|
||||||
|
|
||||||
@@ -245,29 +133,32 @@ always_ff @(posedge clk) begin
|
|||||||
STATE_IDLE: begin
|
STATE_IDLE: begin
|
||||||
dma_wr_desc_req.req_src_addr <= '0;
|
dma_wr_desc_req.req_src_addr <= '0;
|
||||||
|
|
||||||
if (s_axis_cpl.tdest == 0) begin
|
cq_req_cqn_reg <= s_axis_cpl.tdest;
|
||||||
dma_wr_desc_req.req_dst_addr <= txcq_base_addr_reg + 64'(16'(txcq_prod_ptr_reg & ({16{1'b1}} >> (16 - txcq_size_reg))) * 16);
|
|
||||||
phase_tag_reg <= !txcq_prod_ptr_reg[txcq_size_reg];
|
|
||||||
if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin
|
if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin
|
||||||
txcq_prod_ptr_reg <= txcq_prod_ptr_reg + 1;
|
cq_req_valid_reg <= 1'b1;
|
||||||
if (txcq_en_reg) begin
|
state_reg <= STATE_QUERY_CQ;
|
||||||
dma_wr_desc_req.req_valid <= 1'b1;
|
|
||||||
state_reg <= STATE_WRITE_DATA;
|
|
||||||
end else begin
|
end else begin
|
||||||
state_reg <= STATE_IDLE;
|
state_reg <= STATE_IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
STATE_QUERY_CQ: begin
|
||||||
|
dma_wr_desc_req.req_src_addr <= '0;
|
||||||
|
cq_rsp_ready_reg <= 1'b1;
|
||||||
|
|
||||||
|
if (cq_rsp_valid && cq_rsp_ready_reg) begin
|
||||||
|
cq_rsp_ready_reg <= 1'b0;
|
||||||
|
|
||||||
|
dma_wr_desc_req.req_dst_addr <= cq_rsp_addr;
|
||||||
|
phase_tag_reg <= cq_rsp_phase_tag;
|
||||||
|
|
||||||
|
if (cq_rsp_error) begin
|
||||||
|
// drop completion
|
||||||
|
s_axis_cpl.tready <= 1'b1;
|
||||||
|
state_reg <= STATE_IDLE;
|
||||||
end else begin
|
end else begin
|
||||||
dma_wr_desc_req.req_dst_addr <= rxcq_base_addr_reg + 64'(16'(rxcq_prod_ptr_reg & ({16{1'b1}} >> (16 - rxcq_size_reg))) * 16);
|
|
||||||
phase_tag_reg <= !rxcq_prod_ptr_reg[rxcq_size_reg];
|
|
||||||
if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin
|
|
||||||
rxcq_prod_ptr_reg <= rxcq_prod_ptr_reg + 1;
|
|
||||||
if (rxcq_en_reg) begin
|
|
||||||
dma_wr_desc_req.req_valid <= 1'b1;
|
dma_wr_desc_req.req_valid <= 1'b1;
|
||||||
state_reg <= STATE_WRITE_DATA;
|
state_reg <= STATE_WRITE_DATA;
|
||||||
end else begin
|
|
||||||
state_reg <= STATE_IDLE;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -285,8 +176,8 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
state_reg <= STATE_IDLE;
|
state_reg <= STATE_IDLE;
|
||||||
txcq_prod_ptr_reg <= '0;
|
cq_req_valid_reg <= 1'b0;
|
||||||
rxcq_prod_ptr_reg <= '0;
|
cq_rsp_ready_reg <= 1'b0;
|
||||||
irq_reg <= 1'b0;
|
irq_reg <= 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ Authors:
|
|||||||
/*
|
/*
|
||||||
* Corundum-micro descriptor read module
|
* Corundum-micro descriptor read module
|
||||||
*/
|
*/
|
||||||
module cndm_micro_desc_rd
|
module cndm_micro_desc_rd #(
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
parameter CQN_W = 5
|
||||||
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
@@ -38,194 +41,69 @@ module cndm_micro_desc_rd
|
|||||||
taxi_dma_desc_if.sts_snk dma_rd_desc_sts,
|
taxi_dma_desc_if.sts_snk dma_rd_desc_sts,
|
||||||
taxi_dma_ram_if.wr_slv dma_ram_wr,
|
taxi_dma_ram_if.wr_slv dma_ram_wr,
|
||||||
|
|
||||||
input wire logic [1:0] desc_req,
|
taxi_axis_if.snk s_axis_desc_req,
|
||||||
taxi_axis_if.src m_axis_desc
|
taxi_axis_if.src m_axis_desc
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
|
localparam DMA_ADDR_W = dma_rd_desc_req.SRC_ADDR_W;
|
||||||
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
|
|
||||||
|
|
||||||
localparam APB_ADDR_W = s_apb_dp_ctrl.ADDR_W;
|
|
||||||
localparam APB_DATA_W = s_apb_dp_ctrl.DATA_W;
|
|
||||||
|
|
||||||
localparam RAM_ADDR_W = 16;
|
localparam RAM_ADDR_W = 16;
|
||||||
|
|
||||||
logic txq_en_reg = '0;
|
typedef enum logic [2:0] {
|
||||||
logic [3:0] txq_size_reg = '0;
|
QTYPE_EQ,
|
||||||
logic [7:0] txq_cqn_reg = '0;
|
QTYPE_CQ,
|
||||||
logic [63:0] txq_base_addr_reg = '0;
|
QTYPE_SQ,
|
||||||
logic [15:0] txq_prod_reg = '0;
|
QTYPE_RQ
|
||||||
logic rxq_en_reg = '0;
|
} qtype_t;
|
||||||
logic [3:0] rxq_size_reg = '0;
|
|
||||||
logic [7:0] rxq_cqn_reg = '0;
|
|
||||||
logic [63:0] rxq_base_addr_reg = '0;
|
|
||||||
logic [15:0] rxq_prod_reg = '0;
|
|
||||||
|
|
||||||
logic [15:0] txq_cons_ptr_reg = '0;
|
logic [WQN_W-1:0] wq_req_wqn_reg = '0;
|
||||||
logic [15:0] rxq_cons_ptr_reg = '0;
|
logic [2:0] wq_req_qtype_reg = '0;
|
||||||
|
logic wq_req_valid_reg = 1'b0;
|
||||||
|
logic wq_req_ready;
|
||||||
|
logic [CQN_W-1:0] wq_rsp_cqn;
|
||||||
|
logic [DMA_ADDR_W-1:0] wq_rsp_addr;
|
||||||
|
logic wq_rsp_error;
|
||||||
|
logic wq_rsp_valid;
|
||||||
|
logic wq_rsp_ready_reg = 1'b0;
|
||||||
|
|
||||||
logic s_axil_ctrl_awready_reg = 1'b0;
|
cndm_micro_queue_state #(
|
||||||
logic s_axil_ctrl_wready_reg = 1'b0;
|
.QN_W(WQN_W),
|
||||||
logic s_axil_ctrl_bvalid_reg = 1'b0;
|
.DQN_W(CQN_W),
|
||||||
|
.IS_CQ(0),
|
||||||
|
.QTYPE_EN(1),
|
||||||
|
.QE_SIZE(16),
|
||||||
|
.DMA_ADDR_W(DMA_ADDR_W)
|
||||||
|
)
|
||||||
|
wq_mgr_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
logic s_axil_ctrl_arready_reg = 1'b0;
|
/*
|
||||||
logic [AXIL_DATA_W-1:0] s_axil_ctrl_rdata_reg = '0;
|
* Control register interface
|
||||||
logic s_axil_ctrl_rvalid_reg = 1'b0;
|
*/
|
||||||
|
.s_axil_ctrl_wr(s_axil_ctrl_wr),
|
||||||
|
.s_axil_ctrl_rd(s_axil_ctrl_rd),
|
||||||
|
|
||||||
assign s_axil_ctrl_wr.awready = s_axil_ctrl_awready_reg;
|
/*
|
||||||
assign s_axil_ctrl_wr.wready = s_axil_ctrl_wready_reg;
|
* Datapath control register interface
|
||||||
assign s_axil_ctrl_wr.bresp = '0;
|
*/
|
||||||
assign s_axil_ctrl_wr.buser = '0;
|
.s_apb_dp_ctrl(s_apb_dp_ctrl),
|
||||||
assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg;
|
|
||||||
|
|
||||||
assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg;
|
/*
|
||||||
assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg;
|
* Queue management interface
|
||||||
assign s_axil_ctrl_rd.rresp = '0;
|
*/
|
||||||
assign s_axil_ctrl_rd.ruser = '0;
|
.req_qn(wq_req_wqn_reg),
|
||||||
assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg;
|
.req_qtype(wq_req_qtype_reg),
|
||||||
|
.req_valid(wq_req_valid_reg),
|
||||||
logic s_apb_dp_ctrl_pready_reg = 1'b0;
|
.req_ready(wq_req_ready),
|
||||||
logic [AXIL_DATA_W-1:0] s_apb_dp_ctrl_prdata_reg = '0;
|
.rsp_qn(),
|
||||||
|
.rsp_dqn(wq_rsp_cqn),
|
||||||
assign s_apb_dp_ctrl.pready = s_apb_dp_ctrl_pready_reg;
|
.rsp_addr(wq_rsp_addr),
|
||||||
assign s_apb_dp_ctrl.prdata = s_apb_dp_ctrl_prdata_reg;
|
.rsp_phase_tag(),
|
||||||
assign s_apb_dp_ctrl.pslverr = 1'b0;
|
.rsp_error(wq_rsp_error),
|
||||||
assign s_apb_dp_ctrl.pruser = '0;
|
.rsp_valid(wq_rsp_valid),
|
||||||
assign s_apb_dp_ctrl.pbuser = '0;
|
.rsp_ready(wq_rsp_ready_reg)
|
||||||
|
);
|
||||||
always_ff @(posedge clk) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_bvalid_reg <= s_axil_ctrl_bvalid_reg && !s_axil_ctrl_wr.bready;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_rvalid_reg <= s_axil_ctrl_rvalid_reg && !s_axil_ctrl_rd.rready;
|
|
||||||
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b0;
|
|
||||||
|
|
||||||
if (s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_bvalid_reg <= 1'b1;
|
|
||||||
|
|
||||||
case ({s_axil_ctrl_wr.awaddr[9:2], 2'b00})
|
|
||||||
// 10'h000: begin
|
|
||||||
// txq_en_reg <= s_axil_ctrl_wr.wdata[0];
|
|
||||||
// txq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
|
|
||||||
// end
|
|
||||||
10'h004: txq_prod_reg <= s_axil_ctrl_wr.wdata[15:0];
|
|
||||||
// 10'h008: txq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
|
|
||||||
// 10'h00c: txq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
|
|
||||||
|
|
||||||
// 10'h100: begin
|
|
||||||
// rxq_en_reg <= s_axil_ctrl_wr.wdata[0];
|
|
||||||
// rxq_size_reg <= s_axil_ctrl_wr.wdata[19:16];
|
|
||||||
// end
|
|
||||||
10'h104: rxq_prod_reg <= s_axil_ctrl_wr.wdata[15:0];
|
|
||||||
// 10'h108: rxq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata;
|
|
||||||
// 10'h10c: rxq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata;
|
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (s_axil_ctrl_rd.arvalid && !s_axil_ctrl_rvalid_reg) begin
|
|
||||||
s_axil_ctrl_rdata_reg <= '0;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b1;
|
|
||||||
s_axil_ctrl_rvalid_reg <= 1'b1;
|
|
||||||
|
|
||||||
// case ({s_axil_ctrl_rd.araddr[9:2], 2'b00})
|
|
||||||
// 10'h000: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[0] <= txq_en_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[19:16] <= txq_size_reg;
|
|
||||||
// end
|
|
||||||
// 10'h004: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[15:0] <= txq_prod_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[31:16] <= txq_cons_ptr_reg;
|
|
||||||
// end
|
|
||||||
// 10'h008: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[31:0];
|
|
||||||
// 10'h00c: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[63:32];
|
|
||||||
|
|
||||||
// 10'h100: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[0] <= rxq_en_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[19:16] <= rxq_size_reg;
|
|
||||||
// end
|
|
||||||
// 10'h104: begin
|
|
||||||
// s_axil_ctrl_rdata_reg[15:0] <= rxq_prod_reg;
|
|
||||||
// s_axil_ctrl_rdata_reg[31:16] <= rxq_cons_ptr_reg;
|
|
||||||
// end
|
|
||||||
// 10'h108: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[31:0];
|
|
||||||
// 10'h10c: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[63:32];
|
|
||||||
// default: begin end
|
|
||||||
// endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b1;
|
|
||||||
s_apb_dp_ctrl_prdata_reg <= '0;
|
|
||||||
|
|
||||||
if (s_apb_dp_ctrl.pwrite) begin
|
|
||||||
case ({s_apb_dp_ctrl.paddr[9:2], 2'b00})
|
|
||||||
10'h000: begin
|
|
||||||
txq_en_reg <= s_apb_dp_ctrl.pwdata[0];
|
|
||||||
txq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
|
|
||||||
txq_cqn_reg <= s_apb_dp_ctrl.pwdata[31:24];
|
|
||||||
end
|
|
||||||
10'h004: txq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0];
|
|
||||||
10'h008: txq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
10'h00c: txq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
|
|
||||||
10'h100: begin
|
|
||||||
rxq_en_reg <= s_apb_dp_ctrl.pwdata[0];
|
|
||||||
rxq_size_reg <= s_apb_dp_ctrl.pwdata[19:16];
|
|
||||||
rxq_cqn_reg <= s_apb_dp_ctrl.pwdata[31:24];
|
|
||||||
end
|
|
||||||
10'h104: rxq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0];
|
|
||||||
10'h108: rxq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
10'h10c: rxq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata;
|
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
case ({s_apb_dp_ctrl.paddr[9:2], 2'b00})
|
|
||||||
10'h000: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[0] <= txq_en_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[19:16] <= txq_size_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[31:24] <= txq_cqn_reg;
|
|
||||||
end
|
|
||||||
10'h004: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[15:0] <= txq_prod_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[31:16] <= txq_cons_ptr_reg;
|
|
||||||
end
|
|
||||||
10'h008: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[31:0];
|
|
||||||
10'h00c: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[63:32];
|
|
||||||
|
|
||||||
10'h100: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[0] <= rxq_en_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[19:16] <= rxq_size_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[31:24] <= rxq_cqn_reg;
|
|
||||||
end
|
|
||||||
10'h104: begin
|
|
||||||
s_apb_dp_ctrl_prdata_reg[15:0] <= rxq_prod_reg;
|
|
||||||
s_apb_dp_ctrl_prdata_reg[31:16] <= rxq_cons_ptr_reg;
|
|
||||||
end
|
|
||||||
10'h108: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[31:0];
|
|
||||||
10'h10c: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[63:32];
|
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
if (rst) begin
|
|
||||||
s_axil_ctrl_awready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_wready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_bvalid_reg <= 1'b0;
|
|
||||||
|
|
||||||
s_axil_ctrl_arready_reg <= 1'b0;
|
|
||||||
s_axil_ctrl_rvalid_reg <= 1'b0;
|
|
||||||
|
|
||||||
s_apb_dp_ctrl_pready_reg <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
.SRC_ADDR_W(RAM_ADDR_W),
|
.SRC_ADDR_W(RAM_ADDR_W),
|
||||||
@@ -247,18 +125,18 @@ taxi_dma_desc_if #(
|
|||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
|
STATE_QUERY_WQ,
|
||||||
STATE_READ_DESC,
|
STATE_READ_DESC,
|
||||||
STATE_READ_DATA,
|
|
||||||
STATE_TX_DESC
|
STATE_TX_DESC
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
state_t state_reg = STATE_IDLE;
|
state_t state_reg = STATE_IDLE;
|
||||||
|
|
||||||
logic [1:0] desc_req_reg = '0;
|
logic s_axis_desc_req_tready_reg = 1'b0;
|
||||||
|
|
||||||
|
assign s_axis_desc_req.tready = s_axis_desc_req_tready_reg;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
// axis_desc.tready <= 1'b0;
|
|
||||||
|
|
||||||
dma_rd_desc_req.req_src_sel <= '0;
|
dma_rd_desc_req.req_src_sel <= '0;
|
||||||
dma_rd_desc_req.req_src_asid <= '0;
|
dma_rd_desc_req.req_src_asid <= '0;
|
||||||
dma_rd_desc_req.req_dst_sel <= '0;
|
dma_rd_desc_req.req_dst_sel <= '0;
|
||||||
@@ -284,46 +162,45 @@ always_ff @(posedge clk) begin
|
|||||||
dma_desc.req_user <= '0;
|
dma_desc.req_user <= '0;
|
||||||
dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready;
|
dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready;
|
||||||
|
|
||||||
desc_req_reg <= desc_req_reg | desc_req;
|
wq_req_valid_reg <= wq_req_valid_reg && !wq_req_ready;
|
||||||
|
wq_rsp_ready_reg <= 1'b0;
|
||||||
|
|
||||||
if (!txq_en_reg) begin
|
s_axis_desc_req_tready_reg <= 1'b0;
|
||||||
txq_cons_ptr_reg <= '0;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (!rxq_en_reg) begin
|
|
||||||
rxq_cons_ptr_reg <= '0;
|
|
||||||
end
|
|
||||||
|
|
||||||
case (state_reg)
|
case (state_reg)
|
||||||
STATE_IDLE: begin
|
STATE_IDLE: begin
|
||||||
if (desc_req_reg[1]) begin
|
s_axis_desc_req_tready_reg <= 1'b1;
|
||||||
dma_rd_desc_req.req_src_addr <= rxq_base_addr_reg + 64'(16'(rxq_cons_ptr_reg & ({16{1'b1}} >> (16 - rxq_size_reg))) * 16);
|
|
||||||
dma_desc.req_id <= 1'b1;
|
if (s_axis_desc_req.tvalid && s_axis_desc_req.tready) begin
|
||||||
dma_desc.req_dest <= rxq_cqn_reg;
|
s_axis_desc_req_tready_reg <= 1'b0;
|
||||||
desc_req_reg[1] <= 1'b0;
|
wq_req_wqn_reg <= s_axis_desc_req.tdest;
|
||||||
if (rxq_cons_ptr_reg == rxq_prod_reg || !rxq_en_reg) begin
|
wq_req_qtype_reg <= s_axis_desc_req.tuser;
|
||||||
dma_desc.req_user <= 1'b1;
|
wq_req_valid_reg <= 1'b1;
|
||||||
dma_desc.req_valid <= 1'b1;
|
dma_desc.req_id <= s_axis_desc_req.tid;
|
||||||
state_reg <= STATE_TX_DESC;
|
state_reg <= STATE_QUERY_WQ;
|
||||||
end else begin
|
end else begin
|
||||||
dma_desc.req_user <= 1'b0;
|
state_reg <= STATE_IDLE;
|
||||||
dma_rd_desc_req.req_valid <= 1'b1;
|
|
||||||
rxq_cons_ptr_reg <= rxq_cons_ptr_reg + 1;
|
|
||||||
state_reg <= STATE_READ_DESC;
|
|
||||||
end
|
end
|
||||||
end else if (desc_req_reg[0]) begin
|
end
|
||||||
dma_rd_desc_req.req_src_addr <= txq_base_addr_reg + 64'(16'(txq_cons_ptr_reg & ({16{1'b1}} >> (16 - txq_size_reg))) * 16);
|
STATE_QUERY_WQ: begin
|
||||||
dma_desc.req_id <= 1'b0;
|
wq_rsp_ready_reg <= 1'b1;
|
||||||
dma_desc.req_dest <= txq_cqn_reg;
|
|
||||||
desc_req_reg[0] <= 1'b0;
|
if (wq_rsp_valid && wq_rsp_ready_reg) begin
|
||||||
if (txq_cons_ptr_reg == txq_prod_reg || !txq_en_reg) begin
|
wq_rsp_ready_reg <= 1'b0;
|
||||||
|
|
||||||
|
dma_rd_desc_req.req_src_addr <= wq_rsp_addr;
|
||||||
|
|
||||||
|
dma_desc.req_dest <= wq_rsp_cqn;
|
||||||
|
|
||||||
|
if (wq_rsp_error) begin
|
||||||
|
// report error
|
||||||
dma_desc.req_user <= 1'b1;
|
dma_desc.req_user <= 1'b1;
|
||||||
dma_desc.req_valid <= 1'b1;
|
dma_desc.req_valid <= 1'b1;
|
||||||
state_reg <= STATE_TX_DESC;
|
state_reg <= STATE_TX_DESC;
|
||||||
end else begin
|
end else begin
|
||||||
|
// read desc
|
||||||
dma_desc.req_user <= 1'b0;
|
dma_desc.req_user <= 1'b0;
|
||||||
dma_rd_desc_req.req_valid <= 1'b1;
|
dma_rd_desc_req.req_valid <= 1'b1;
|
||||||
txq_cons_ptr_reg <= txq_cons_ptr_reg + 1;
|
|
||||||
state_reg <= STATE_READ_DESC;
|
state_reg <= STATE_READ_DESC;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,10 +18,20 @@ Authors:
|
|||||||
module cndm_micro_dp_mgr #
|
module cndm_micro_dp_mgr #
|
||||||
(
|
(
|
||||||
parameter PORTS = 2,
|
parameter PORTS = 2,
|
||||||
|
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
parameter CQN_W = WQN_W,
|
||||||
|
|
||||||
parameter logic PTP_EN = 1'b1,
|
parameter logic PTP_EN = 1'b1,
|
||||||
parameter PTP_BASE_ADDR_DP = 0,
|
parameter PTP_BASE_ADDR_DP = 0,
|
||||||
|
|
||||||
parameter PORT_BASE_ADDR_DP = 0,
|
parameter PORT_BASE_ADDR_DP = 0,
|
||||||
parameter PORT_BASE_ADDR_HOST = 0
|
parameter PORT_BASE_ADDR_HOST = 0,
|
||||||
|
parameter PORT_STRIDE = 'h10000,
|
||||||
|
parameter WQ_REG_STRIDE = 32,
|
||||||
|
parameter QM_OFFSET = 'h0000,
|
||||||
|
parameter CQM_OFFSET = 'h4000,
|
||||||
|
parameter PORT_CTRL_OFFSET = 'h8000
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
@@ -76,6 +86,13 @@ typedef enum logic [15:0] {
|
|||||||
CMD_OP_DESTROY_QP = 16'h0243
|
CMD_OP_DESTROY_QP = 16'h0243
|
||||||
} cmd_opcode_t;
|
} cmd_opcode_t;
|
||||||
|
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
QTYPE_EQ,
|
||||||
|
QTYPE_CQ,
|
||||||
|
QTYPE_SQ,
|
||||||
|
QTYPE_RQ
|
||||||
|
} qtype_t;
|
||||||
|
|
||||||
typedef enum logic [4:0] {
|
typedef enum logic [4:0] {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
STATE_START,
|
STATE_START,
|
||||||
@@ -86,9 +103,12 @@ typedef enum logic [4:0] {
|
|||||||
STATE_CREATE_Q_FIND_2,
|
STATE_CREATE_Q_FIND_2,
|
||||||
STATE_CREATE_Q_RESET_1,
|
STATE_CREATE_Q_RESET_1,
|
||||||
STATE_CREATE_Q_RESET_2,
|
STATE_CREATE_Q_RESET_2,
|
||||||
|
STATE_CREATE_Q_RESET_3,
|
||||||
STATE_CREATE_Q_SET_BASE_L,
|
STATE_CREATE_Q_SET_BASE_L,
|
||||||
STATE_CREATE_Q_SET_BASE_H,
|
STATE_CREATE_Q_SET_BASE_H,
|
||||||
|
STATE_CREATE_Q_SET_DQN,
|
||||||
STATE_CREATE_Q_ENABLE,
|
STATE_CREATE_Q_ENABLE,
|
||||||
|
STATE_CREATE_Q_PORT_CONFIG,
|
||||||
STATE_DESTROY_Q_DISABLE,
|
STATE_DESTROY_Q_DISABLE,
|
||||||
STATE_PTP_READ_1,
|
STATE_PTP_READ_1,
|
||||||
STATE_PTP_READ_2,
|
STATE_PTP_READ_2,
|
||||||
@@ -155,6 +175,7 @@ logic [31:0] flags_reg = '0, flags_next;
|
|||||||
logic [15:0] port_reg = '0, port_next;
|
logic [15:0] port_reg = '0, port_next;
|
||||||
logic [23:0] qn_reg = '0, qn_next;
|
logic [23:0] qn_reg = '0, qn_next;
|
||||||
logic [23:0] qn2_reg = '0, qn2_next;
|
logic [23:0] qn2_reg = '0, qn2_next;
|
||||||
|
logic [2:0] qtype_reg = '0, qtype_next;
|
||||||
|
|
||||||
logic [3:0] cmd_ptr_reg = '0, cmd_ptr_next;
|
logic [3:0] cmd_ptr_reg = '0, cmd_ptr_next;
|
||||||
logic [DP_APB_ADDR_W-1:0] dp_ptr_reg = '0, dp_ptr_next;
|
logic [DP_APB_ADDR_W-1:0] dp_ptr_reg = '0, dp_ptr_next;
|
||||||
@@ -194,6 +215,7 @@ always_comb begin
|
|||||||
port_next = port_reg;
|
port_next = port_reg;
|
||||||
qn_next = qn_reg;
|
qn_next = qn_reg;
|
||||||
qn2_next = qn2_reg;
|
qn2_next = qn2_reg;
|
||||||
|
qtype_next = qtype_reg;
|
||||||
|
|
||||||
cmd_ptr_next = cmd_ptr_reg;
|
cmd_ptr_next = cmd_ptr_reg;
|
||||||
dp_ptr_next = dp_ptr_reg;
|
dp_ptr_next = dp_ptr_reg;
|
||||||
@@ -247,9 +269,9 @@ always_comb begin
|
|||||||
|
|
||||||
// determine block base address
|
// determine block base address
|
||||||
case (opcode_reg)
|
case (opcode_reg)
|
||||||
|
// // EQ
|
||||||
// CMD_OP_CREATE_EQ:
|
// CMD_OP_CREATE_EQ:
|
||||||
// begin
|
// begin
|
||||||
// // EQ
|
|
||||||
// qn_next = 0;
|
// qn_next = 0;
|
||||||
// dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
// dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
||||||
// host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST;
|
// host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST;
|
||||||
@@ -258,54 +280,56 @@ always_comb begin
|
|||||||
// CMD_OP_QUERY_EQ,
|
// CMD_OP_QUERY_EQ,
|
||||||
// CMD_OP_DESTROY_EQ:
|
// CMD_OP_DESTROY_EQ:
|
||||||
// begin
|
// begin
|
||||||
// // EQ
|
|
||||||
// dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
// dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
||||||
// host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST;
|
// host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST;
|
||||||
// end
|
// end
|
||||||
|
// CQ
|
||||||
CMD_OP_CREATE_CQ:
|
CMD_OP_CREATE_CQ:
|
||||||
begin
|
begin
|
||||||
// CQ
|
cnt_next = 2**CQN_W-1;
|
||||||
cnt_next = 1;
|
qtype_next = QTYPE_CQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + CQM_OFFSET + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + CQM_OFFSET + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
CMD_OP_MODIFY_CQ,
|
CMD_OP_MODIFY_CQ,
|
||||||
CMD_OP_QUERY_CQ,
|
CMD_OP_QUERY_CQ,
|
||||||
CMD_OP_DESTROY_CQ:
|
CMD_OP_DESTROY_CQ:
|
||||||
begin
|
begin
|
||||||
// CQ
|
qtype_next = QTYPE_CQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000 | {qn_reg, 8'd00}) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + CQM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h8000 | {qn_reg, 8'd00}) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + CQM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
|
// SQ
|
||||||
CMD_OP_CREATE_SQ:
|
CMD_OP_CREATE_SQ:
|
||||||
begin
|
begin
|
||||||
// SQ
|
cnt_next = 2**WQN_W-1;
|
||||||
cnt_next = 0;
|
qtype_next = QTYPE_SQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + QM_OFFSET + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h0000) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + QM_OFFSET + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
CMD_OP_MODIFY_SQ,
|
CMD_OP_MODIFY_SQ,
|
||||||
CMD_OP_QUERY_SQ,
|
CMD_OP_QUERY_SQ,
|
||||||
CMD_OP_DESTROY_SQ:
|
CMD_OP_DESTROY_SQ:
|
||||||
begin
|
begin
|
||||||
// SQ
|
qtype_next = QTYPE_SQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + QM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h0000) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + QM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
|
// RQ
|
||||||
CMD_OP_CREATE_RQ:
|
CMD_OP_CREATE_RQ:
|
||||||
begin
|
begin
|
||||||
// RQ
|
cnt_next = 2**WQN_W-1;
|
||||||
cnt_next = 0;
|
qtype_next = QTYPE_RQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + QM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h0100) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + QM_OFFSET + (qn_reg * WQ_REG_STRIDE) + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
CMD_OP_MODIFY_RQ,
|
CMD_OP_MODIFY_RQ,
|
||||||
CMD_OP_QUERY_RQ,
|
CMD_OP_QUERY_RQ,
|
||||||
CMD_OP_DESTROY_RQ:
|
CMD_OP_DESTROY_RQ:
|
||||||
begin
|
begin
|
||||||
// RQ
|
qtype_next = QTYPE_RQ;
|
||||||
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP);
|
dp_ptr_next = DP_APB_ADDR_W'((port_reg * PORT_STRIDE) + QM_OFFSET + PORT_BASE_ADDR_DP);
|
||||||
host_ptr_next = 32'({port_reg, 16'd0} | 'h0100) + PORT_BASE_ADDR_HOST;
|
host_ptr_next = (port_reg * PORT_STRIDE) + QM_OFFSET + PORT_BASE_ADDR_HOST;
|
||||||
end
|
end
|
||||||
default: begin end
|
default: begin end
|
||||||
endcase
|
endcase
|
||||||
@@ -470,7 +494,8 @@ always_comb begin
|
|||||||
end else begin
|
end else begin
|
||||||
// queue is active
|
// queue is active
|
||||||
qn_next = qn_reg + 1;
|
qn_next = qn_reg + 1;
|
||||||
dp_ptr_next = dp_ptr_reg + 'h100;
|
dp_ptr_next = dp_ptr_reg + WQ_REG_STRIDE;
|
||||||
|
host_ptr_next = host_ptr_reg + WQ_REG_STRIDE;
|
||||||
if (cnt_reg == 0) begin
|
if (cnt_reg == 0) begin
|
||||||
// no more queues
|
// no more queues
|
||||||
m_axis_rsp_tdata_next = '0; // TODO
|
m_axis_rsp_tdata_next = '0; // TODO
|
||||||
@@ -511,12 +536,27 @@ always_comb begin
|
|||||||
// reset queue 2
|
// reset queue 2
|
||||||
|
|
||||||
// store doorbell offset
|
// store doorbell offset
|
||||||
cmd_ram_wr_data = host_ptr_reg + 'h0004;
|
cmd_ram_wr_data = host_ptr_reg + 'h0008;
|
||||||
cmd_ram_wr_addr = 7;
|
cmd_ram_wr_addr = 7;
|
||||||
cmd_ram_wr_en = 1'b1;
|
cmd_ram_wr_en = 1'b1;
|
||||||
|
|
||||||
if (!m_apb_dp_ctrl_psel_reg) begin
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0004;
|
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0008;
|
||||||
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
|
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
|
||||||
|
m_apb_dp_ctrl_pstrb_next = '1;
|
||||||
|
|
||||||
|
state_next = STATE_CREATE_Q_RESET_3;
|
||||||
|
end else begin
|
||||||
|
state_next = STATE_CREATE_Q_RESET_2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_CREATE_Q_RESET_3: begin
|
||||||
|
// reset queue 2
|
||||||
|
|
||||||
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
|
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h000c;
|
||||||
m_apb_dp_ctrl_psel_next = 1'b1;
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
|
m_apb_dp_ctrl_pwdata_next = 32'h00000000;
|
||||||
@@ -524,14 +564,14 @@ always_comb begin
|
|||||||
|
|
||||||
state_next = STATE_CREATE_Q_SET_BASE_L;
|
state_next = STATE_CREATE_Q_SET_BASE_L;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = STATE_CREATE_Q_RESET_2;
|
state_next = STATE_CREATE_Q_RESET_3;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
STATE_CREATE_Q_SET_BASE_L: begin
|
STATE_CREATE_Q_SET_BASE_L: begin
|
||||||
// set queue base addr (LSB)
|
// set queue base addr (LSB)
|
||||||
cmd_ram_rd_addr = 8;
|
cmd_ram_rd_addr = 8;
|
||||||
if (!m_apb_dp_ctrl_psel_reg) begin
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0008;
|
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0018;
|
||||||
m_apb_dp_ctrl_psel_next = 1'b1;
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
|
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
|
||||||
@@ -546,7 +586,7 @@ always_comb begin
|
|||||||
// set queue base addr (MSB)
|
// set queue base addr (MSB)
|
||||||
cmd_ram_rd_addr = 9;
|
cmd_ram_rd_addr = 9;
|
||||||
if (!m_apb_dp_ctrl_psel_reg) begin
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h000C;
|
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h001C;
|
||||||
m_apb_dp_ctrl_psel_next = 1'b1;
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
|
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
|
||||||
@@ -554,7 +594,22 @@ always_comb begin
|
|||||||
|
|
||||||
state_next = STATE_CREATE_Q_ENABLE;
|
state_next = STATE_CREATE_Q_ENABLE;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = STATE_CREATE_Q_SET_BASE_H;
|
state_next = STATE_CREATE_Q_SET_DQN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_CREATE_Q_SET_DQN: begin
|
||||||
|
// set CQN/EQN/IRQN
|
||||||
|
cmd_ram_rd_addr = 4;
|
||||||
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
|
m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0004;
|
||||||
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
|
m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data;
|
||||||
|
m_apb_dp_ctrl_pstrb_next = '1;
|
||||||
|
|
||||||
|
state_next = STATE_CREATE_Q_ENABLE;
|
||||||
|
end else begin
|
||||||
|
state_next = STATE_CREATE_Q_SET_DQN;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
STATE_CREATE_Q_ENABLE: begin
|
STATE_CREATE_Q_ENABLE: begin
|
||||||
@@ -565,9 +620,27 @@ always_comb begin
|
|||||||
m_apb_dp_ctrl_psel_next = 1'b1;
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
m_apb_dp_ctrl_pwrite_next = 1'b1;
|
||||||
m_apb_dp_ctrl_pwdata_next = '0;
|
m_apb_dp_ctrl_pwdata_next = '0;
|
||||||
m_apb_dp_ctrl_pwdata_next[31:24] = qn2_reg[7:0];
|
m_apb_dp_ctrl_pwdata_next[23:20] = 4'(qtype_reg); // type
|
||||||
m_apb_dp_ctrl_pwdata_next[19:16] = cmd_ram_rd_data[3:0];
|
m_apb_dp_ctrl_pwdata_next[19:16] = cmd_ram_rd_data[3:0]; // size
|
||||||
m_apb_dp_ctrl_pwdata_next[0] = 1'b1;
|
m_apb_dp_ctrl_pwdata_next[0] = 1'b1; // enable
|
||||||
|
m_apb_dp_ctrl_pstrb_next = '1;
|
||||||
|
|
||||||
|
state_next = STATE_CREATE_Q_PORT_CONFIG;
|
||||||
|
end else begin
|
||||||
|
state_next = STATE_CREATE_Q_ENABLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_CREATE_Q_PORT_CONFIG: begin
|
||||||
|
// set up port
|
||||||
|
if (!m_apb_dp_ctrl_psel_reg) begin
|
||||||
|
if (qtype_reg == QTYPE_SQ) begin
|
||||||
|
m_apb_dp_ctrl_paddr_next = DP_APB_ADDR_W'(PORT_BASE_ADDR_DP + (port_reg * PORT_STRIDE) + PORT_CTRL_OFFSET + 'h0010);
|
||||||
|
end else begin
|
||||||
|
m_apb_dp_ctrl_paddr_next = DP_APB_ADDR_W'(PORT_BASE_ADDR_DP + (port_reg * PORT_STRIDE) + PORT_CTRL_OFFSET + 'h0020);
|
||||||
|
end
|
||||||
|
m_apb_dp_ctrl_psel_next = 1'b1;
|
||||||
|
m_apb_dp_ctrl_pwrite_next = qtype_reg == QTYPE_SQ || qtype_reg == QTYPE_RQ;
|
||||||
|
m_apb_dp_ctrl_pwdata_next = 32'(qn_reg);
|
||||||
m_apb_dp_ctrl_pstrb_next = '1;
|
m_apb_dp_ctrl_pstrb_next = '1;
|
||||||
|
|
||||||
m_axis_rsp_tdata_next = '0; // TODO
|
m_axis_rsp_tdata_next = '0; // TODO
|
||||||
@@ -576,7 +649,7 @@ always_comb begin
|
|||||||
|
|
||||||
state_next = STATE_SEND_RSP;
|
state_next = STATE_SEND_RSP;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = STATE_CREATE_Q_ENABLE;
|
state_next = STATE_CREATE_Q_PORT_CONFIG;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
STATE_DESTROY_Q_DISABLE: begin
|
STATE_DESTROY_Q_DISABLE: begin
|
||||||
@@ -822,6 +895,7 @@ always_ff @(posedge clk) begin
|
|||||||
port_reg <= port_next;
|
port_reg <= port_next;
|
||||||
qn_reg <= qn_next;
|
qn_reg <= qn_next;
|
||||||
qn2_reg <= qn2_next;
|
qn2_reg <= qn2_next;
|
||||||
|
qtype_reg <= qtype_next;
|
||||||
|
|
||||||
cmd_ptr_reg <= cmd_ptr_next;
|
cmd_ptr_reg <= cmd_ptr_next;
|
||||||
dp_ptr_reg <= dp_ptr_next;
|
dp_ptr_reg <= dp_ptr_next;
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ module cndm_micro_pcie_us #(
|
|||||||
// Structural configuration
|
// Structural configuration
|
||||||
parameter PORTS = 2,
|
parameter PORTS = 2,
|
||||||
|
|
||||||
|
// Queue configuration
|
||||||
|
parameter CQN_W = 5,
|
||||||
|
|
||||||
// PTP configuration
|
// PTP configuration
|
||||||
parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
||||||
@@ -510,6 +513,9 @@ cndm_micro_core #(
|
|||||||
// Structural configuration
|
// Structural configuration
|
||||||
.PORTS(PORTS),
|
.PORTS(PORTS),
|
||||||
|
|
||||||
|
// Queue configuration
|
||||||
|
.CQN_W(CQN_W),
|
||||||
|
|
||||||
// PTP configuration
|
// PTP configuration
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ Authors:
|
|||||||
* Corundum-micro port module
|
* Corundum-micro port module
|
||||||
*/
|
*/
|
||||||
module cndm_micro_port #(
|
module cndm_micro_port #(
|
||||||
|
// Queue configuration
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
parameter CQN_W = WQN_W,
|
||||||
|
|
||||||
|
// PTP configuration
|
||||||
parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b0
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
@@ -69,15 +74,20 @@ module cndm_micro_port #(
|
|||||||
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
|
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
|
||||||
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
|
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
|
||||||
|
|
||||||
|
localparam APB_ADDR_W = s_apb_dp_ctrl.ADDR_W;
|
||||||
|
localparam APB_DATA_W = s_apb_dp_ctrl.DATA_W;
|
||||||
|
|
||||||
localparam RAM_SEGS = dma_ram_wr.SEGS;
|
localparam RAM_SEGS = dma_ram_wr.SEGS;
|
||||||
localparam RAM_SEG_ADDR_W = dma_ram_wr.SEG_ADDR_W;
|
localparam RAM_SEG_ADDR_W = dma_ram_wr.SEG_ADDR_W;
|
||||||
localparam RAM_SEG_DATA_W = dma_ram_wr.SEG_DATA_W;
|
localparam RAM_SEG_DATA_W = dma_ram_wr.SEG_DATA_W;
|
||||||
localparam RAM_SEG_BE_W = dma_ram_wr.SEG_BE_W;
|
localparam RAM_SEG_BE_W = dma_ram_wr.SEG_BE_W;
|
||||||
localparam RAM_SEL_W = dma_ram_wr.SEL_W;
|
localparam RAM_SEL_W = dma_ram_wr.SEL_W;
|
||||||
|
|
||||||
|
localparam PORT_ADDR_W = 14;
|
||||||
|
|
||||||
taxi_axil_if #(
|
taxi_axil_if #(
|
||||||
.DATA_W(s_axil_ctrl_wr.DATA_W),
|
.DATA_W(s_axil_ctrl_wr.DATA_W),
|
||||||
.ADDR_W(15),
|
.ADDR_W(PORT_ADDR_W),
|
||||||
.STRB_W(s_axil_ctrl_wr.STRB_W),
|
.STRB_W(s_axil_ctrl_wr.STRB_W),
|
||||||
.AWUSER_EN(s_axil_ctrl_wr.AWUSER_EN),
|
.AWUSER_EN(s_axil_ctrl_wr.AWUSER_EN),
|
||||||
.AWUSER_W(s_axil_ctrl_wr.AWUSER_W),
|
.AWUSER_W(s_axil_ctrl_wr.AWUSER_W),
|
||||||
@@ -97,7 +107,7 @@ taxi_axil_interconnect_1s #(
|
|||||||
.ADDR_W(s_axil_ctrl_wr.ADDR_W),
|
.ADDR_W(s_axil_ctrl_wr.ADDR_W),
|
||||||
.M_REGIONS(1),
|
.M_REGIONS(1),
|
||||||
.M_BASE_ADDR('0),
|
.M_BASE_ADDR('0),
|
||||||
.M_ADDR_W({$size(axil_ctrl){{1{32'd15}}}}),
|
.M_ADDR_W({$size(axil_ctrl){{1{32'd14}}}}),
|
||||||
.M_SECURE({$size(axil_ctrl){1'b0}})
|
.M_SECURE({$size(axil_ctrl){1'b0}})
|
||||||
)
|
)
|
||||||
port_intercon_inst (
|
port_intercon_inst (
|
||||||
@@ -119,16 +129,16 @@ port_intercon_inst (
|
|||||||
|
|
||||||
taxi_apb_if #(
|
taxi_apb_if #(
|
||||||
.DATA_W(32),
|
.DATA_W(32),
|
||||||
.ADDR_W(15)
|
.ADDR_W(PORT_ADDR_W)
|
||||||
)
|
)
|
||||||
apb_dp_ctrl[2]();
|
apb_dp_ctrl[3]();
|
||||||
|
|
||||||
taxi_apb_interconnect #(
|
taxi_apb_interconnect #(
|
||||||
.M_CNT($size(apb_dp_ctrl)),
|
.M_CNT($size(apb_dp_ctrl)),
|
||||||
.ADDR_W(s_apb_dp_ctrl.ADDR_W),
|
.ADDR_W(s_apb_dp_ctrl.ADDR_W),
|
||||||
.M_REGIONS(1),
|
.M_REGIONS(1),
|
||||||
.M_BASE_ADDR('0),
|
.M_BASE_ADDR('0),
|
||||||
.M_ADDR_W({$size(apb_dp_ctrl){{1{32'd15}}}}),
|
.M_ADDR_W({$size(apb_dp_ctrl){{1{32'd14}}}}),
|
||||||
.M_SECURE({$size(apb_dp_ctrl){1'b0}})
|
.M_SECURE({$size(apb_dp_ctrl){1'b0}})
|
||||||
)
|
)
|
||||||
port_dp_intercon_inst (
|
port_dp_intercon_inst (
|
||||||
@@ -146,6 +156,47 @@ port_dp_intercon_inst (
|
|||||||
.m_apb(apb_dp_ctrl)
|
.m_apb(apb_dp_ctrl)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Port control registers
|
||||||
|
|
||||||
|
logic apb_dp_ctrl_pready_reg = 1'b0;
|
||||||
|
logic [APB_DATA_W-1:0] apb_dp_ctrl_prdata_reg = '0;
|
||||||
|
|
||||||
|
assign apb_dp_ctrl[2].pready = apb_dp_ctrl_pready_reg;
|
||||||
|
assign apb_dp_ctrl[2].prdata = apb_dp_ctrl_prdata_reg;
|
||||||
|
assign apb_dp_ctrl[2].pslverr = 1'b0;
|
||||||
|
assign apb_dp_ctrl[2].pruser = '0;
|
||||||
|
assign apb_dp_ctrl[2].pbuser = '0;
|
||||||
|
|
||||||
|
logic [WQN_W-1:0] tx_queue_reg = '0;
|
||||||
|
logic [WQN_W-1:0] rx_queue_reg = '0;
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
apb_dp_ctrl_pready_reg <= 1'b0;
|
||||||
|
|
||||||
|
if (apb_dp_ctrl[2].penable && apb_dp_ctrl[2].psel && !apb_dp_ctrl_pready_reg) begin
|
||||||
|
apb_dp_ctrl_pready_reg <= 1'b1;
|
||||||
|
apb_dp_ctrl_prdata_reg <= '0;
|
||||||
|
|
||||||
|
if (apb_dp_ctrl[2].pwrite) begin
|
||||||
|
case (8'({apb_dp_ctrl[2].paddr >> 2, 2'b00}))
|
||||||
|
8'h10: tx_queue_reg <= WQN_W'(apb_dp_ctrl[2].pwdata);
|
||||||
|
8'h20: rx_queue_reg <= WQN_W'(apb_dp_ctrl[2].pwdata);
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
case (8'({apb_dp_ctrl[2].paddr >> 2, 2'b00}))
|
||||||
|
8'h10: apb_dp_ctrl_prdata_reg <= 32'(tx_queue_reg);
|
||||||
|
8'h20: apb_dp_ctrl_prdata_reg <= 32'(rx_queue_reg);
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (rst) begin
|
||||||
|
apb_dp_ctrl_pready_reg <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
.SRC_ADDR_W(dma_rd_desc_req.SRC_ADDR_W),
|
.SRC_ADDR_W(dma_rd_desc_req.SRC_ADDR_W),
|
||||||
.SRC_SEL_EN(dma_rd_desc_req.SRC_SEL_EN),
|
.SRC_SEL_EN(dma_rd_desc_req.SRC_SEL_EN),
|
||||||
@@ -262,7 +313,50 @@ wr_dma_mux_inst (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// descriptor fetch
|
// descriptor fetch
|
||||||
wire [1:0] desc_req;
|
taxi_axis_if #(
|
||||||
|
.DATA_W(8),
|
||||||
|
.KEEP_EN(0),
|
||||||
|
.LAST_EN(1),
|
||||||
|
.ID_EN(1),
|
||||||
|
.ID_W(1),
|
||||||
|
.DEST_EN(1),
|
||||||
|
.DEST_W(WQN_W),
|
||||||
|
.USER_EN(1),
|
||||||
|
.USER_W(3)
|
||||||
|
) axis_desc_req();
|
||||||
|
|
||||||
|
taxi_axis_if #(
|
||||||
|
.DATA_W(8),
|
||||||
|
.KEEP_EN(0),
|
||||||
|
.LAST_EN(1),
|
||||||
|
.ID_EN(1),
|
||||||
|
.ID_W(1),
|
||||||
|
.DEST_EN(1),
|
||||||
|
.DEST_W(WQN_W),
|
||||||
|
.USER_EN(1),
|
||||||
|
.USER_W(3)
|
||||||
|
) axis_desc_req_txrx[2]();
|
||||||
|
|
||||||
|
taxi_axis_arb_mux #(
|
||||||
|
.S_COUNT(2),
|
||||||
|
.UPDATE_TID(1),
|
||||||
|
.ARB_ROUND_ROBIN(0),
|
||||||
|
.ARB_LSB_HIGH_PRIO(0) // prefer RX requests
|
||||||
|
)
|
||||||
|
desc_req_mux_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AXI4-Stream input (sink)
|
||||||
|
*/
|
||||||
|
.s_axis(axis_desc_req_txrx),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AXI4-Stream output (source)
|
||||||
|
*/
|
||||||
|
.m_axis(axis_desc_req)
|
||||||
|
);
|
||||||
|
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(16*8),
|
.DATA_W(16*8),
|
||||||
@@ -271,12 +365,15 @@ taxi_axis_if #(
|
|||||||
.ID_EN(1),
|
.ID_EN(1),
|
||||||
.ID_W(1),
|
.ID_W(1),
|
||||||
.DEST_EN(1),
|
.DEST_EN(1),
|
||||||
.DEST_W(8),
|
.DEST_W(WQN_W),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(1)
|
||||||
) axis_desc();
|
) axis_desc();
|
||||||
|
|
||||||
cndm_micro_desc_rd
|
cndm_micro_desc_rd #(
|
||||||
|
.WQN_W(WQN_W),
|
||||||
|
.CQN_W(CQN_W)
|
||||||
|
)
|
||||||
desc_rd_inst (
|
desc_rd_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
@@ -299,22 +396,21 @@ desc_rd_inst (
|
|||||||
.dma_rd_desc_sts(dma_rd_desc_int[0]),
|
.dma_rd_desc_sts(dma_rd_desc_int[0]),
|
||||||
.dma_ram_wr(dma_ram_wr_int[0]),
|
.dma_ram_wr(dma_ram_wr_int[0]),
|
||||||
|
|
||||||
.desc_req(desc_req),
|
.s_axis_desc_req(axis_desc_req),
|
||||||
.m_axis_desc(axis_desc)
|
.m_axis_desc(axis_desc)
|
||||||
);
|
);
|
||||||
|
|
||||||
// desc demux
|
// desc demux
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(axis_desc.DATA_W),
|
.DATA_W(16*8),
|
||||||
.KEEP_EN(axis_desc.KEEP_EN),
|
.KEEP_EN(1),
|
||||||
.KEEP_W(axis_desc.KEEP_W),
|
.LAST_EN(1),
|
||||||
.LAST_EN(axis_desc.LAST_EN),
|
.ID_EN(1),
|
||||||
.ID_EN(axis_desc.ID_EN),
|
.ID_W(1),
|
||||||
.ID_W(axis_desc.ID_W),
|
.DEST_EN(1),
|
||||||
.DEST_EN(axis_desc.DEST_EN),
|
.DEST_W(WQN_W),
|
||||||
.DEST_W(axis_desc.DEST_W),
|
.USER_EN(1),
|
||||||
.USER_EN(axis_desc.USER_EN),
|
.USER_W(1)
|
||||||
.USER_W(axis_desc.USER_W)
|
|
||||||
) axis_desc_txrx[2]();
|
) axis_desc_txrx[2]();
|
||||||
|
|
||||||
taxi_axis_demux #(
|
taxi_axis_demux #(
|
||||||
@@ -350,21 +446,18 @@ taxi_axis_if #(
|
|||||||
.LAST_EN(1),
|
.LAST_EN(1),
|
||||||
.ID_EN(0),
|
.ID_EN(0),
|
||||||
.DEST_EN(1),
|
.DEST_EN(1),
|
||||||
.DEST_W(8),
|
.DEST_W(CQN_W),
|
||||||
.USER_EN(0)
|
.USER_EN(0)
|
||||||
) axis_cpl();
|
) axis_cpl();
|
||||||
|
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(axis_cpl.DATA_W),
|
.DATA_W(16*8),
|
||||||
.KEEP_EN(axis_cpl.KEEP_EN),
|
.KEEP_EN(1),
|
||||||
.KEEP_W(axis_cpl.KEEP_W),
|
.LAST_EN(1),
|
||||||
.LAST_EN(axis_cpl.LAST_EN),
|
.ID_EN(0),
|
||||||
.ID_EN(axis_cpl.ID_EN),
|
.DEST_EN(1),
|
||||||
.ID_W(axis_cpl.ID_W),
|
.DEST_W(CQN_W),
|
||||||
.DEST_EN(axis_cpl.DEST_EN),
|
.USER_EN(0)
|
||||||
.DEST_W(axis_cpl.DEST_W),
|
|
||||||
.USER_EN(axis_cpl.USER_EN),
|
|
||||||
.USER_W(axis_cpl.USER_W)
|
|
||||||
) axis_cpl_txrx[2]();
|
) axis_cpl_txrx[2]();
|
||||||
|
|
||||||
taxi_axis_arb_mux #(
|
taxi_axis_arb_mux #(
|
||||||
@@ -387,7 +480,9 @@ cpl_mux_inst (
|
|||||||
.m_axis(axis_cpl)
|
.m_axis(axis_cpl)
|
||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_cpl_wr
|
cndm_micro_cpl_wr #(
|
||||||
|
.CQN_W(CQN_W)
|
||||||
|
)
|
||||||
cpl_wr_inst (
|
cpl_wr_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
@@ -416,12 +511,12 @@ cpl_wr_inst (
|
|||||||
|
|
||||||
// TX path
|
// TX path
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(mac_axis_tx.DATA_W),
|
.DATA_W(mac_axis_tx.DATA_W*2),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(1)
|
||||||
) mac_tx_int();
|
) mac_tx_int();
|
||||||
|
|
||||||
taxi_axis_async_fifo #(
|
taxi_axis_async_fifo_adapter #(
|
||||||
.DEPTH(16384),
|
.DEPTH(16384),
|
||||||
.RAM_PIPELINE(2),
|
.RAM_PIPELINE(2),
|
||||||
.FRAME_FIFO(1),
|
.FRAME_FIFO(1),
|
||||||
@@ -527,6 +622,8 @@ tx_cpl_fifo (
|
|||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_tx #(
|
cndm_micro_tx #(
|
||||||
|
.WQN_W(WQN_W),
|
||||||
|
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
@@ -548,7 +645,8 @@ tx_inst (
|
|||||||
.dma_rd_desc_sts(dma_rd_desc_int[1]),
|
.dma_rd_desc_sts(dma_rd_desc_int[1]),
|
||||||
.dma_ram_wr(dma_ram_wr_int[1]),
|
.dma_ram_wr(dma_ram_wr_int[1]),
|
||||||
|
|
||||||
.desc_req(desc_req[0]),
|
.tx_queue(tx_queue_reg),
|
||||||
|
.m_axis_desc_req(axis_desc_req_txrx[0]),
|
||||||
.s_axis_desc(axis_desc_txrx[0]),
|
.s_axis_desc(axis_desc_txrx[0]),
|
||||||
.tx_data(mac_tx_int),
|
.tx_data(mac_tx_int),
|
||||||
.tx_cpl(mac_tx_cpl_int),
|
.tx_cpl(mac_tx_cpl_int),
|
||||||
@@ -557,13 +655,13 @@ tx_inst (
|
|||||||
|
|
||||||
// RX path
|
// RX path
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(mac_axis_rx.DATA_W),
|
.DATA_W(mac_axis_rx.DATA_W*2),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(mac_axis_rx.USER_W)
|
.USER_W(mac_axis_rx.USER_W)
|
||||||
) mac_rx_int();
|
) mac_rx_int();
|
||||||
|
|
||||||
taxi_axis_async_fifo #(
|
taxi_axis_async_fifo_adapter #(
|
||||||
.DEPTH(16384),
|
.DEPTH(32768),
|
||||||
.RAM_PIPELINE(2),
|
.RAM_PIPELINE(2),
|
||||||
.FRAME_FIFO(1),
|
.FRAME_FIFO(1),
|
||||||
.USER_BAD_FRAME_VALUE(1'b1),
|
.USER_BAD_FRAME_VALUE(1'b1),
|
||||||
@@ -611,6 +709,8 @@ rx_fifo (
|
|||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_rx #(
|
cndm_micro_rx #(
|
||||||
|
.WQN_W(WQN_W),
|
||||||
|
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
@@ -633,7 +733,8 @@ rx_inst (
|
|||||||
.dma_ram_rd(dma_ram_rd_int[1]),
|
.dma_ram_rd(dma_ram_rd_int[1]),
|
||||||
|
|
||||||
.rx_data(mac_rx_int),
|
.rx_data(mac_rx_int),
|
||||||
.desc_req(desc_req[1]),
|
.rx_queue(rx_queue_reg),
|
||||||
|
.m_axis_desc_req(axis_desc_req_txrx[1]),
|
||||||
.s_axis_desc(axis_desc_txrx[1]),
|
.s_axis_desc(axis_desc_txrx[1]),
|
||||||
.m_axis_cpl(axis_cpl_txrx[1])
|
.m_axis_cpl(axis_cpl_txrx[1])
|
||||||
);
|
);
|
||||||
|
|||||||
341
src/cndm/rtl/cndm_micro_queue_state.sv
Normal file
341
src/cndm/rtl/cndm_micro_queue_state.sv
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2026 FPGA Ninja, LLC
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
- Alex Forencich
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
`resetall
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
`default_nettype none
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corundum-micro queue state manager module
|
||||||
|
*/
|
||||||
|
module cndm_micro_queue_state #(
|
||||||
|
parameter QN_W = 5,
|
||||||
|
parameter DQN_W = 5,
|
||||||
|
parameter logic IS_CQ = 1'b0,
|
||||||
|
parameter logic QTYPE_EN = !IS_CQ,
|
||||||
|
parameter QE_SIZE = 16,
|
||||||
|
parameter DMA_ADDR_W = 64
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire logic clk,
|
||||||
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control register interface
|
||||||
|
*/
|
||||||
|
taxi_axil_if.wr_slv s_axil_ctrl_wr,
|
||||||
|
taxi_axil_if.rd_slv s_axil_ctrl_rd,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Datapath control register interface
|
||||||
|
*/
|
||||||
|
taxi_apb_if.slv s_apb_dp_ctrl,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Queue management interface
|
||||||
|
*/
|
||||||
|
input wire logic [QN_W-1:0] req_qn,
|
||||||
|
input wire logic [2:0] req_qtype,
|
||||||
|
input wire logic req_valid,
|
||||||
|
output wire logic req_ready,
|
||||||
|
output wire logic [QN_W-1:0] rsp_qn,
|
||||||
|
output wire logic [DQN_W-1:0] rsp_dqn,
|
||||||
|
output wire logic [DMA_ADDR_W-1:0] rsp_addr,
|
||||||
|
output wire logic rsp_phase_tag,
|
||||||
|
output wire logic rsp_error,
|
||||||
|
output wire logic rsp_valid,
|
||||||
|
input wire logic rsp_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam PTR_W = 16;
|
||||||
|
|
||||||
|
localparam ADDR_W = QN_W+5;
|
||||||
|
|
||||||
|
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W;
|
||||||
|
localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W;
|
||||||
|
|
||||||
|
localparam APB_ADDR_W = s_apb_dp_ctrl.ADDR_W;
|
||||||
|
localparam APB_DATA_W = s_apb_dp_ctrl.DATA_W;
|
||||||
|
|
||||||
|
// check configuration
|
||||||
|
if (s_axil_ctrl_rd.DATA_W != 32 || s_axil_ctrl_wr.DATA_W != 32)
|
||||||
|
$fatal(0, "Error: AXI data width must be 32 (instance %m)");
|
||||||
|
|
||||||
|
if (s_axil_ctrl_rd.ADDR_W < ADDR_W || s_axil_ctrl_wr.ADDR_W < ADDR_W)
|
||||||
|
$fatal(0, "Error: AXI address width is insufficient (instance %m)");
|
||||||
|
|
||||||
|
if (s_apb_dp_ctrl.DATA_W != 32)
|
||||||
|
$fatal(0, "Error: APB data width must be 32 (instance %m)");
|
||||||
|
|
||||||
|
if (s_apb_dp_ctrl.ADDR_W < ADDR_W)
|
||||||
|
$fatal(0, "Error: APB address width is insufficient (instance %m)");
|
||||||
|
|
||||||
|
logic s_axil_ctrl_awready_reg = 1'b0, s_axil_ctrl_awready_next;
|
||||||
|
logic s_axil_ctrl_wready_reg = 1'b0, s_axil_ctrl_wready_next;
|
||||||
|
logic s_axil_ctrl_bvalid_reg = 1'b0, s_axil_ctrl_bvalid_next;
|
||||||
|
|
||||||
|
logic s_axil_ctrl_arready_reg = 1'b0, s_axil_ctrl_arready_next;
|
||||||
|
logic [AXIL_DATA_W-1:0] s_axil_ctrl_rdata_reg = '0, s_axil_ctrl_rdata_next;
|
||||||
|
logic s_axil_ctrl_rvalid_reg = 1'b0, s_axil_ctrl_rvalid_next;
|
||||||
|
|
||||||
|
assign s_axil_ctrl_wr.awready = s_axil_ctrl_awready_reg;
|
||||||
|
assign s_axil_ctrl_wr.wready = s_axil_ctrl_wready_reg;
|
||||||
|
assign s_axil_ctrl_wr.bresp = '0;
|
||||||
|
assign s_axil_ctrl_wr.buser = '0;
|
||||||
|
assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg;
|
||||||
|
|
||||||
|
assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg;
|
||||||
|
assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg;
|
||||||
|
assign s_axil_ctrl_rd.rresp = '0;
|
||||||
|
assign s_axil_ctrl_rd.ruser = '0;
|
||||||
|
assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg;
|
||||||
|
|
||||||
|
wire [QN_W-1:0] s_axil_ctrl_awaddr_queue_index = s_axil_ctrl_wr.awaddr[5 +: QN_W];
|
||||||
|
wire [2:0] s_axil_ctrl_awaddr_reg_index = s_axil_ctrl_wr.awaddr[4:2];
|
||||||
|
wire [QN_W-1:0] s_axil_ctrl_araddr_queue_index = s_axil_ctrl_rd.araddr[5 +: QN_W];
|
||||||
|
wire [2:0] s_axil_ctrl_araddr_reg_index = s_axil_ctrl_rd.araddr[4:2];
|
||||||
|
|
||||||
|
logic s_apb_dp_ctrl_pready_reg = 1'b0, s_apb_dp_ctrl_pready_next;
|
||||||
|
logic [AXIL_DATA_W-1:0] s_apb_dp_ctrl_prdata_reg = '0, s_apb_dp_ctrl_prdata_next;
|
||||||
|
|
||||||
|
assign s_apb_dp_ctrl.pready = s_apb_dp_ctrl_pready_reg;
|
||||||
|
assign s_apb_dp_ctrl.prdata = s_apb_dp_ctrl_prdata_reg;
|
||||||
|
assign s_apb_dp_ctrl.pslverr = 1'b0;
|
||||||
|
assign s_apb_dp_ctrl.pruser = '0;
|
||||||
|
assign s_apb_dp_ctrl.pbuser = '0;
|
||||||
|
|
||||||
|
wire [QN_W-1:0] s_apb_dp_ctrl_paddr_queue_index = s_apb_dp_ctrl.paddr[5 +: QN_W];
|
||||||
|
wire [2:0] s_apb_dp_ctrl_paddr_reg_index = s_apb_dp_ctrl.paddr[4:2];
|
||||||
|
|
||||||
|
logic req_ready_reg = 1'b0, req_ready_next;
|
||||||
|
logic [QN_W-1:0] rsp_qn_reg = '0, rsp_qn_next;
|
||||||
|
logic [DQN_W-1:0] rsp_dqn_reg = '0, rsp_dqn_next;
|
||||||
|
logic [DMA_ADDR_W-1:0] rsp_addr_reg = '0, rsp_addr_next;
|
||||||
|
logic rsp_phase_tag_reg = 1'b0, rsp_phase_tag_next;
|
||||||
|
logic rsp_error_reg = 1'b0, rsp_error_next;
|
||||||
|
logic rsp_valid_reg = 1'b0, rsp_valid_next;
|
||||||
|
|
||||||
|
assign req_ready = req_ready_reg;
|
||||||
|
assign rsp_qn = rsp_qn_reg;
|
||||||
|
assign rsp_dqn = rsp_dqn_reg;
|
||||||
|
assign rsp_addr = rsp_addr_reg;
|
||||||
|
assign rsp_phase_tag = rsp_phase_tag_reg;
|
||||||
|
assign rsp_error = rsp_error_reg;
|
||||||
|
assign rsp_valid = rsp_valid_reg;
|
||||||
|
|
||||||
|
logic [2**QN_W-1:0] queue_enable_reg = '0;
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [2:0] queue_mem_qtype[2**QN_W] = '{default: '0};
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [DQN_W-1:0] queue_mem_dqn[2**QN_W] = '{default: '0};
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [3:0] queue_mem_log_size[2**QN_W] = '{default: '0};
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [DMA_ADDR_W-1:0] queue_mem_base_addr[2**QN_W] = '{default: '0};
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [PTR_W-1:0] queue_mem_prod_ptr[2**QN_W] = '{default: '0};
|
||||||
|
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
|
||||||
|
logic [PTR_W-1:0] queue_mem_cons_ptr[2**QN_W] = '{default: '0};
|
||||||
|
|
||||||
|
logic queue_mem_wr_en;
|
||||||
|
logic [QN_W-1:0] queue_mem_addr;
|
||||||
|
|
||||||
|
wire queue_mem_rd_enable = queue_enable_reg[queue_mem_addr];
|
||||||
|
wire [2:0] queue_mem_rd_qtype = queue_mem_qtype[queue_mem_addr];
|
||||||
|
wire [DQN_W-1:0] queue_mem_rd_dqn = queue_mem_dqn[queue_mem_addr];
|
||||||
|
wire [3:0] queue_mem_rd_log_size = queue_mem_log_size[queue_mem_addr];
|
||||||
|
wire [DMA_ADDR_W-1:0] queue_mem_rd_base_addr = queue_mem_base_addr[queue_mem_addr];
|
||||||
|
wire [PTR_W-1:0] queue_mem_rd_prod_ptr = queue_mem_prod_ptr[queue_mem_addr];
|
||||||
|
wire [PTR_W-1:0] queue_mem_rd_cons_ptr = queue_mem_cons_ptr[queue_mem_addr];
|
||||||
|
|
||||||
|
logic queue_mem_wr_enable;
|
||||||
|
logic [2:0] queue_mem_wr_qtype;
|
||||||
|
logic [DQN_W-1:0] queue_mem_wr_dqn;
|
||||||
|
logic [3:0] queue_mem_wr_log_size;
|
||||||
|
logic [DMA_ADDR_W-1:0] queue_mem_wr_base_addr;
|
||||||
|
logic [PTR_W-1:0] queue_mem_wr_prod_ptr;
|
||||||
|
logic [PTR_W-1:0] queue_mem_wr_cons_ptr;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_axil_ctrl_awready_next = 1'b0;
|
||||||
|
s_axil_ctrl_wready_next = 1'b0;
|
||||||
|
s_axil_ctrl_bvalid_next = 1'b0;
|
||||||
|
|
||||||
|
s_axil_ctrl_arready_next = 1'b0;
|
||||||
|
s_axil_ctrl_rdata_next = s_axil_ctrl_rdata_reg;
|
||||||
|
s_axil_ctrl_rvalid_next = 1'b0;
|
||||||
|
|
||||||
|
s_apb_dp_ctrl_pready_next = 1'b0;
|
||||||
|
s_apb_dp_ctrl_prdata_next = s_apb_dp_ctrl_prdata_reg;
|
||||||
|
|
||||||
|
req_ready_next = 1'b0;
|
||||||
|
rsp_qn_next = rsp_qn_reg;
|
||||||
|
rsp_dqn_next = rsp_dqn_reg;
|
||||||
|
rsp_addr_next = rsp_addr_reg;
|
||||||
|
rsp_phase_tag_next = rsp_phase_tag_reg;
|
||||||
|
rsp_error_next = rsp_error_reg;
|
||||||
|
rsp_valid_next = rsp_valid_reg && !rsp_ready;
|
||||||
|
|
||||||
|
queue_mem_wr_en = 1'b0;
|
||||||
|
queue_mem_addr = '0;
|
||||||
|
|
||||||
|
queue_mem_wr_enable = queue_mem_rd_enable;
|
||||||
|
queue_mem_wr_qtype = queue_mem_rd_qtype;
|
||||||
|
queue_mem_wr_dqn = queue_mem_rd_dqn;
|
||||||
|
queue_mem_wr_log_size = queue_mem_rd_log_size;
|
||||||
|
queue_mem_wr_base_addr = queue_mem_rd_base_addr;
|
||||||
|
queue_mem_wr_prod_ptr = queue_mem_rd_prod_ptr;
|
||||||
|
queue_mem_wr_cons_ptr = queue_mem_rd_cons_ptr;
|
||||||
|
|
||||||
|
// terminate AXI lite writes
|
||||||
|
if (IS_CQ && s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin
|
||||||
|
s_axil_ctrl_awready_next = 1'b1;
|
||||||
|
s_axil_ctrl_wready_next = 1'b1;
|
||||||
|
s_axil_ctrl_bvalid_next = 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// terminate AXI lite reads
|
||||||
|
if (s_axil_ctrl_rd.arvalid && !s_axil_ctrl_rvalid_reg) begin
|
||||||
|
s_axil_ctrl_rdata_next = '0;
|
||||||
|
|
||||||
|
s_axil_ctrl_arready_next = 1'b1;
|
||||||
|
s_axil_ctrl_rvalid_next = 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (!IS_CQ && s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin
|
||||||
|
// AXI lite write
|
||||||
|
s_axil_ctrl_awready_next = 1'b1;
|
||||||
|
s_axil_ctrl_wready_next = 1'b1;
|
||||||
|
s_axil_ctrl_bvalid_next = 1'b1;
|
||||||
|
|
||||||
|
queue_mem_wr_en = 1'b1;
|
||||||
|
queue_mem_addr = s_axil_ctrl_awaddr_queue_index;
|
||||||
|
|
||||||
|
case (s_axil_ctrl_awaddr_reg_index)
|
||||||
|
3'd2: queue_mem_wr_prod_ptr = s_axil_ctrl_wr.wdata[15:0];
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
end else if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin
|
||||||
|
// APB read/write
|
||||||
|
s_apb_dp_ctrl_pready_next = 1'b1;
|
||||||
|
s_apb_dp_ctrl_prdata_next = '0;
|
||||||
|
|
||||||
|
queue_mem_addr = s_apb_dp_ctrl_paddr_queue_index;
|
||||||
|
|
||||||
|
if (s_apb_dp_ctrl.pwrite) begin
|
||||||
|
queue_mem_wr_en = 1'b1;
|
||||||
|
|
||||||
|
case (s_apb_dp_ctrl_paddr_reg_index)
|
||||||
|
3'd0: begin
|
||||||
|
queue_mem_wr_enable = s_apb_dp_ctrl.pwdata[0];
|
||||||
|
queue_mem_wr_log_size = s_apb_dp_ctrl.pwdata[19:16];
|
||||||
|
queue_mem_wr_qtype = 3'(s_apb_dp_ctrl.pwdata[23:20]);
|
||||||
|
end
|
||||||
|
3'd1: queue_mem_wr_dqn = s_apb_dp_ctrl.pwdata[DQN_W-1:0];
|
||||||
|
3'd2: queue_mem_wr_prod_ptr = s_apb_dp_ctrl.pwdata[15:0];
|
||||||
|
3'd3: queue_mem_wr_cons_ptr = s_apb_dp_ctrl.pwdata[15:0];
|
||||||
|
3'd6: queue_mem_wr_base_addr[31:0] = s_apb_dp_ctrl.pwdata;
|
||||||
|
3'd7: queue_mem_wr_base_addr[63:32] = s_apb_dp_ctrl.pwdata;
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
case (s_apb_dp_ctrl_paddr_reg_index)
|
||||||
|
3'd0: begin
|
||||||
|
s_apb_dp_ctrl_prdata_next[0] = queue_mem_rd_enable;
|
||||||
|
s_apb_dp_ctrl_prdata_next[19:16] = queue_mem_rd_log_size;
|
||||||
|
s_apb_dp_ctrl_prdata_next[23:20] = 4'(queue_mem_rd_qtype);
|
||||||
|
end
|
||||||
|
3'd1: s_apb_dp_ctrl_prdata_next = 32'(queue_mem_rd_dqn);
|
||||||
|
3'd2: s_apb_dp_ctrl_prdata_next[15:0] = queue_mem_rd_prod_ptr;
|
||||||
|
3'd3: s_apb_dp_ctrl_prdata_next[15:0] = IS_CQ ? '0 : queue_mem_rd_cons_ptr;
|
||||||
|
3'd6: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[31:0];
|
||||||
|
3'd7: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[63:32];
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
end else if (req_valid && !req_ready && (!rsp_valid || rsp_ready)) begin
|
||||||
|
// completion enqueue request
|
||||||
|
req_ready_next = 1'b1;
|
||||||
|
|
||||||
|
queue_mem_addr = req_qn;
|
||||||
|
|
||||||
|
rsp_qn_next = req_qn;
|
||||||
|
rsp_dqn_next = queue_mem_rd_dqn;
|
||||||
|
rsp_error_next = !queue_mem_rd_enable || (QTYPE_EN && req_qtype != queue_mem_rd_qtype);
|
||||||
|
if (IS_CQ) begin
|
||||||
|
rsp_addr_next = queue_mem_rd_base_addr + DMA_ADDR_W'(16'(queue_mem_rd_prod_ptr & ({16{1'b1}} >> (16 - queue_mem_rd_log_size))) * QE_SIZE);
|
||||||
|
rsp_phase_tag_next = !queue_mem_rd_prod_ptr[queue_mem_rd_log_size];
|
||||||
|
queue_mem_wr_prod_ptr = queue_mem_rd_prod_ptr + 1;
|
||||||
|
end else begin
|
||||||
|
rsp_addr_next = queue_mem_rd_base_addr + DMA_ADDR_W'(16'(queue_mem_rd_cons_ptr & ({16{1'b1}} >> (16 - queue_mem_rd_log_size))) * QE_SIZE);
|
||||||
|
if (queue_mem_rd_prod_ptr == queue_mem_rd_cons_ptr)
|
||||||
|
rsp_error_next = 1'b1;
|
||||||
|
queue_mem_wr_cons_ptr = queue_mem_rd_cons_ptr + 1;
|
||||||
|
end
|
||||||
|
rsp_valid_next = 1'b1;
|
||||||
|
|
||||||
|
if (!rsp_error_next) begin
|
||||||
|
queue_mem_wr_en = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
s_axil_ctrl_awready_reg <= s_axil_ctrl_awready_next;
|
||||||
|
s_axil_ctrl_wready_reg <= s_axil_ctrl_wready_next;
|
||||||
|
s_axil_ctrl_bvalid_reg <= s_axil_ctrl_bvalid_next;
|
||||||
|
|
||||||
|
s_axil_ctrl_arready_reg <= s_axil_ctrl_arready_next;
|
||||||
|
s_axil_ctrl_rdata_reg <= s_axil_ctrl_rdata_next;
|
||||||
|
s_axil_ctrl_rvalid_reg <= s_axil_ctrl_rvalid_next;
|
||||||
|
|
||||||
|
s_apb_dp_ctrl_pready_reg <= s_apb_dp_ctrl_pready_next;
|
||||||
|
s_apb_dp_ctrl_prdata_reg <= s_apb_dp_ctrl_prdata_next;
|
||||||
|
|
||||||
|
req_ready_reg <= req_ready_next;
|
||||||
|
rsp_qn_reg <= rsp_qn_next;
|
||||||
|
rsp_dqn_reg <= rsp_dqn_next;
|
||||||
|
rsp_addr_reg <= rsp_addr_next;
|
||||||
|
rsp_phase_tag_reg <= rsp_phase_tag_next;
|
||||||
|
rsp_error_reg <= rsp_error_next;
|
||||||
|
rsp_valid_reg <= rsp_valid_next;
|
||||||
|
|
||||||
|
if (queue_mem_wr_en) begin
|
||||||
|
queue_enable_reg[queue_mem_addr] <= queue_mem_wr_enable;
|
||||||
|
queue_mem_qtype[queue_mem_addr] <= queue_mem_wr_qtype;
|
||||||
|
queue_mem_dqn[queue_mem_addr] <= queue_mem_wr_dqn;
|
||||||
|
queue_mem_log_size[queue_mem_addr] <= queue_mem_wr_log_size;
|
||||||
|
queue_mem_base_addr[queue_mem_addr] <= queue_mem_wr_base_addr;
|
||||||
|
queue_mem_prod_ptr[queue_mem_addr] <= queue_mem_wr_prod_ptr;
|
||||||
|
queue_mem_cons_ptr[queue_mem_addr] <= queue_mem_wr_cons_ptr;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (rst) begin
|
||||||
|
s_axil_ctrl_awready_reg <= 1'b0;
|
||||||
|
s_axil_ctrl_wready_reg <= 1'b0;
|
||||||
|
s_axil_ctrl_bvalid_reg <= 1'b0;
|
||||||
|
|
||||||
|
s_axil_ctrl_arready_reg <= 1'b0;
|
||||||
|
s_axil_ctrl_rvalid_reg <= 1'b0;
|
||||||
|
|
||||||
|
s_apb_dp_ctrl_pready_reg <= 1'b0;
|
||||||
|
|
||||||
|
req_ready_reg <= 1'b0;
|
||||||
|
rsp_valid_reg <= 1'b0;
|
||||||
|
|
||||||
|
queue_enable_reg <= '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
||||||
@@ -16,6 +16,8 @@ Authors:
|
|||||||
* Corundum-micro receive datapath
|
* Corundum-micro receive datapath
|
||||||
*/
|
*/
|
||||||
module cndm_micro_rx #(
|
module cndm_micro_rx #(
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
|
||||||
parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b0
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
@@ -38,13 +40,21 @@ module cndm_micro_rx #(
|
|||||||
taxi_dma_ram_if.rd_slv dma_ram_rd,
|
taxi_dma_ram_if.rd_slv dma_ram_rd,
|
||||||
|
|
||||||
taxi_axis_if.snk rx_data,
|
taxi_axis_if.snk rx_data,
|
||||||
output wire logic desc_req,
|
input wire logic [WQN_W-1:0] rx_queue,
|
||||||
|
taxi_axis_if.src m_axis_desc_req,
|
||||||
taxi_axis_if.snk s_axis_desc,
|
taxi_axis_if.snk s_axis_desc,
|
||||||
taxi_axis_if.src m_axis_cpl
|
taxi_axis_if.src m_axis_cpl
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam RAM_ADDR_W = 16;
|
localparam RAM_ADDR_W = 16;
|
||||||
|
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
QTYPE_EQ,
|
||||||
|
QTYPE_CQ,
|
||||||
|
QTYPE_SQ,
|
||||||
|
QTYPE_RQ
|
||||||
|
} qtype_t;
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
.SRC_ADDR_W(RAM_ADDR_W),
|
.SRC_ADDR_W(RAM_ADDR_W),
|
||||||
.SRC_SEL_EN(1'b0),
|
.SRC_SEL_EN(1'b0),
|
||||||
@@ -70,9 +80,18 @@ typedef enum logic [1:0] {
|
|||||||
|
|
||||||
state_t state_reg = STATE_IDLE;
|
state_t state_reg = STATE_IDLE;
|
||||||
|
|
||||||
logic desc_req_reg = 1'b0;
|
logic m_axis_desc_req_tvalid_reg = 1'b0;
|
||||||
|
logic [WQN_W-1:0] m_axis_desc_req_tdest_reg = '0;
|
||||||
|
logic [2:0] m_axis_desc_req_tuser_reg = '0;
|
||||||
|
|
||||||
assign desc_req = desc_req_reg;
|
assign m_axis_desc_req.tdata = '0;
|
||||||
|
assign m_axis_desc_req.tkeep = '0;
|
||||||
|
assign m_axis_desc_req.tstrb = '0;
|
||||||
|
assign m_axis_desc_req.tlast = 1'b1;
|
||||||
|
assign m_axis_desc_req.tvalid = m_axis_desc_req_tvalid_reg;
|
||||||
|
assign m_axis_desc_req.tid = '0;
|
||||||
|
assign m_axis_desc_req.tdest = rx_queue;
|
||||||
|
assign m_axis_desc_req.tuser = m_axis_desc_req_tuser_reg;
|
||||||
|
|
||||||
wire [95:0] rx_ptp_ts;
|
wire [95:0] rx_ptp_ts;
|
||||||
wire rx_ptp_ts_valid;
|
wire rx_ptp_ts_valid;
|
||||||
@@ -153,7 +172,7 @@ end else begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
desc_req_reg <= 1'b0;
|
m_axis_desc_req_tvalid_reg <= m_axis_desc_req_tvalid_reg && !m_axis_desc_req.tready;
|
||||||
|
|
||||||
s_axis_desc.tready <= 1'b0;
|
s_axis_desc.tready <= 1'b0;
|
||||||
|
|
||||||
@@ -205,7 +224,9 @@ always_ff @(posedge clk) begin
|
|||||||
dma_wr_desc_req.req_len <= 20'(dma_desc.sts_len);
|
dma_wr_desc_req.req_len <= 20'(dma_desc.sts_len);
|
||||||
m_axis_cpl.tdata[47:32] <= 16'(dma_desc.sts_len);
|
m_axis_cpl.tdata[47:32] <= 16'(dma_desc.sts_len);
|
||||||
if (dma_desc.sts_valid) begin
|
if (dma_desc.sts_valid) begin
|
||||||
desc_req_reg <= 1'b1;
|
m_axis_desc_req_tvalid_reg <= 1'b1;
|
||||||
|
m_axis_desc_req_tdest_reg <= rx_queue;
|
||||||
|
m_axis_desc_req_tuser_reg <= QTYPE_RQ;
|
||||||
state_reg <= STATE_READ_DESC;
|
state_reg <= STATE_READ_DESC;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ Authors:
|
|||||||
* Corundum-micro transmit datapath
|
* Corundum-micro transmit datapath
|
||||||
*/
|
*/
|
||||||
module cndm_micro_tx #(
|
module cndm_micro_tx #(
|
||||||
|
parameter WQN_W = 5,
|
||||||
|
|
||||||
parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b0
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
@@ -37,7 +39,8 @@ module cndm_micro_tx #(
|
|||||||
taxi_dma_desc_if.sts_snk dma_rd_desc_sts,
|
taxi_dma_desc_if.sts_snk dma_rd_desc_sts,
|
||||||
taxi_dma_ram_if.wr_slv dma_ram_wr,
|
taxi_dma_ram_if.wr_slv dma_ram_wr,
|
||||||
|
|
||||||
output wire logic desc_req,
|
input wire logic [WQN_W-1:0] tx_queue,
|
||||||
|
taxi_axis_if.src m_axis_desc_req,
|
||||||
taxi_axis_if.snk s_axis_desc,
|
taxi_axis_if.snk s_axis_desc,
|
||||||
taxi_axis_if.src tx_data,
|
taxi_axis_if.src tx_data,
|
||||||
taxi_axis_if.snk tx_cpl,
|
taxi_axis_if.snk tx_cpl,
|
||||||
@@ -46,6 +49,13 @@ module cndm_micro_tx #(
|
|||||||
|
|
||||||
localparam RAM_ADDR_W = 16;
|
localparam RAM_ADDR_W = 16;
|
||||||
|
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
QTYPE_EQ,
|
||||||
|
QTYPE_CQ,
|
||||||
|
QTYPE_SQ,
|
||||||
|
QTYPE_RQ
|
||||||
|
} qtype_t;
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
.SRC_ADDR_W(RAM_ADDR_W),
|
.SRC_ADDR_W(RAM_ADDR_W),
|
||||||
.SRC_SEL_EN(1'b0),
|
.SRC_SEL_EN(1'b0),
|
||||||
@@ -71,9 +81,18 @@ typedef enum logic [1:0] {
|
|||||||
|
|
||||||
state_t state_reg = STATE_IDLE;
|
state_t state_reg = STATE_IDLE;
|
||||||
|
|
||||||
logic desc_req_reg = 1'b0;
|
logic m_axis_desc_req_tvalid_reg = 1'b0;
|
||||||
|
logic [WQN_W-1:0] m_axis_desc_req_tdest_reg = '0;
|
||||||
|
logic [2:0] m_axis_desc_req_tuser_reg = '0;
|
||||||
|
|
||||||
assign desc_req = desc_req_reg;
|
assign m_axis_desc_req.tdata = '0;
|
||||||
|
assign m_axis_desc_req.tkeep = '0;
|
||||||
|
assign m_axis_desc_req.tstrb = '0;
|
||||||
|
assign m_axis_desc_req.tlast = 1'b1;
|
||||||
|
assign m_axis_desc_req.tvalid = m_axis_desc_req_tvalid_reg;
|
||||||
|
assign m_axis_desc_req.tid = '0;
|
||||||
|
assign m_axis_desc_req.tdest = m_axis_desc_req_tdest_reg;
|
||||||
|
assign m_axis_desc_req.tuser = m_axis_desc_req_tuser_reg;
|
||||||
|
|
||||||
wire [95:0] tx_cpl_ptp_ts;
|
wire [95:0] tx_cpl_ptp_ts;
|
||||||
wire tx_cpl_valid;
|
wire tx_cpl_valid;
|
||||||
@@ -138,7 +157,7 @@ end else begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
desc_req_reg <= 1'b0;
|
m_axis_desc_req_tvalid_reg <= m_axis_desc_req_tvalid_reg && !m_axis_desc_req.tready;
|
||||||
|
|
||||||
s_axis_desc.tready <= 1'b0;
|
s_axis_desc.tready <= 1'b0;
|
||||||
|
|
||||||
@@ -175,7 +194,10 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
case (state_reg)
|
case (state_reg)
|
||||||
STATE_IDLE: begin
|
STATE_IDLE: begin
|
||||||
desc_req_reg <= 1'b1;
|
m_axis_desc_req_tvalid_reg <= 1'b1;
|
||||||
|
m_axis_desc_req_tdest_reg <= tx_queue;
|
||||||
|
m_axis_desc_req_tuser_reg <= QTYPE_SQ;
|
||||||
|
|
||||||
state_reg <= STATE_READ_DESC;
|
state_reg <= STATE_READ_DESC;
|
||||||
end
|
end
|
||||||
STATE_READ_DESC: begin
|
STATE_READ_DESC: begin
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ class Cq:
|
|||||||
|
|
||||||
self.cons_ptr = None
|
self.cons_ptr = None
|
||||||
|
|
||||||
|
self.db_offset = None
|
||||||
|
|
||||||
self.hw_regs = self.driver.hw_regs
|
self.hw_regs = self.driver.hw_regs
|
||||||
|
|
||||||
async def open(self, irqn, size):
|
async def open(self, irqn, size):
|
||||||
@@ -128,6 +130,13 @@ class Cq:
|
|||||||
rsp_unpacked = struct.unpack("<HHLLLLLLLQQLLLL", rsp)
|
rsp_unpacked = struct.unpack("<HHLLLLLLLQQLLLL", rsp)
|
||||||
print(rsp_unpacked)
|
print(rsp_unpacked)
|
||||||
self.cqn = rsp_unpacked[4]
|
self.cqn = rsp_unpacked[4]
|
||||||
|
self.db_offset = rsp_unpacked[8]
|
||||||
|
|
||||||
|
if self.db_offset == 0:
|
||||||
|
self.cqn = None
|
||||||
|
self.db_offset = None
|
||||||
|
self.log.error("Failed to allocate CQ")
|
||||||
|
return
|
||||||
|
|
||||||
self.log.info("Opened CQ %d", self.cqn)
|
self.log.info("Opened CQ %d", self.cqn)
|
||||||
|
|
||||||
@@ -242,7 +251,13 @@ class Sq:
|
|||||||
self.sqn = rsp_unpacked[4]
|
self.sqn = rsp_unpacked[4]
|
||||||
self.db_offset = rsp_unpacked[8]
|
self.db_offset = rsp_unpacked[8]
|
||||||
|
|
||||||
self.log.info("Opened SQ %d", self.sqn)
|
if self.db_offset == 0:
|
||||||
|
self.sqn = None
|
||||||
|
self.db_offset = None
|
||||||
|
self.log.error("Failed to allocate SQ")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log.info("Opened SQ %d (CQ %d)", self.sqn, cq.cqn)
|
||||||
|
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
@@ -408,7 +423,13 @@ class Rq:
|
|||||||
self.rqn = rsp_unpacked[4]
|
self.rqn = rsp_unpacked[4]
|
||||||
self.db_offset = rsp_unpacked[8]
|
self.db_offset = rsp_unpacked[8]
|
||||||
|
|
||||||
self.log.info("Opened RQ %d", self.rqn)
|
if self.db_offset == 0:
|
||||||
|
self.rqn = None
|
||||||
|
self.db_offset = None
|
||||||
|
self.log.error("Failed to allocate RQ")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log.info("Opened RQ %d (CQ %d)", self.rqn, cq.cqn)
|
||||||
|
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
@@ -522,30 +543,38 @@ class Port:
|
|||||||
self.index = index
|
self.index = index
|
||||||
self.hw_regs = driver.hw_regs
|
self.hw_regs = driver.hw_regs
|
||||||
|
|
||||||
self.rxq = None
|
self.rxq_count = 1
|
||||||
self.rxcq = None
|
self.rxq = []
|
||||||
|
|
||||||
self.txq = None
|
self.txq_count = 1
|
||||||
self.txcq = None
|
self.txq = []
|
||||||
|
|
||||||
self.rx_queue = Queue()
|
self.rx_queue = Queue()
|
||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
|
await self.open()
|
||||||
|
|
||||||
self.rxcq = Cq(self.driver, self)
|
async def open(self):
|
||||||
await self.rxcq.open(self.index, 256)
|
for k in range(self.rxq_count):
|
||||||
|
cq = Cq(self.driver, self)
|
||||||
|
await cq.open(self.index, 256)
|
||||||
|
|
||||||
self.rxq = Rq(self.driver, self)
|
q = Rq(self.driver, self)
|
||||||
await self.rxq.open(self.rxcq, 256)
|
await q.open(cq, 256)
|
||||||
|
|
||||||
self.txcq = Cq(self.driver, self)
|
self.rxq.append(q)
|
||||||
await self.txcq.open(self.index, 256)
|
|
||||||
|
|
||||||
self.txq = Sq(self.driver, self)
|
for k in range(self.txq_count):
|
||||||
await self.txq.open(self.txcq, 256)
|
cq = Cq(self.driver, self)
|
||||||
|
await cq.open(self.index, 256)
|
||||||
|
|
||||||
async def start_xmit(self, data):
|
q = Sq(self.driver, self)
|
||||||
await self.txq.start_xmit(data)
|
await q.open(cq, 256)
|
||||||
|
|
||||||
|
self.txq.append(q)
|
||||||
|
|
||||||
|
async def start_xmit(self, data, tx_ring=0):
|
||||||
|
await self.txq[tx_ring].start_xmit(data)
|
||||||
|
|
||||||
async def recv(self):
|
async def recv(self):
|
||||||
return await self.rx_queue.get()
|
return await self.rx_queue.get()
|
||||||
@@ -555,8 +584,10 @@ class Port:
|
|||||||
|
|
||||||
async def interrupt_handler(self):
|
async def interrupt_handler(self):
|
||||||
self.log.info("Interrupt")
|
self.log.info("Interrupt")
|
||||||
await self.rxcq.handler(self.rxcq)
|
for q in self.rxq:
|
||||||
await self.txcq.handler(self.txcq)
|
await q.cq.handler(q.cq)
|
||||||
|
for q in self.txq:
|
||||||
|
await q.cq.handler(q.cq)
|
||||||
|
|
||||||
|
|
||||||
class Driver:
|
class Driver:
|
||||||
|
|||||||
Reference in New Issue
Block a user