参考
Vitis HLS.csdn
Vitis HLS流水灯测试.csdn
嵌入式协程Protothread.csdn
myhdl.csdn
Amaranth HDL.csdn
| 类别 | Verilog | C / 嵌入式 | 说明 |
|---|---|---|---|
| 时钟 / 循环 | always @(posedge clk) |
for(;;) 或主循环 |
时钟触发逻辑 ↔ 主循环轮询 |
| 延时 /定时 | #5 / #10ns |
usleep(5) / HAL_Delay(5) |
硬件延时 ↔ 软件延时 |
| 复位 / 初始化 | if (rst) / posedge rst / rst_n |
init(); / memset() / if(!rst_n) |
硬件复位 ↔ 软件初始化 |
| 状态机 | state <= IDLE/BUSY/DONE / next_state <= ... |
enum {IDLE,BUSY,DONE}; state = next_state; |
硬件状态机 ↔ 软件状态机 |
| 条件判断 | if (enable) ... else ... |
if(enable){...} else {...} |
逻辑判断 |
| 循环 | for(i=0;i<N;i++) / while(cond) |
for(...) / while(...) |
串行操作 / 循环 |
| 输入握手 | i_valid / wr_en |
while(!ready); send(data); / HAL 写函数 |
输入数据准备 / 写总线 |
| 输出握手 | o_ready / done |
检查返回标志 / while(!done) |
输出完成 / 任务完成 |
| 中断 / 事件 | irq / posedge capture_event |
ISR() / if(event_flag) |
硬件中断 / 软件中断处理 |
| 并行 /串行 | a <= b; c <= d; / shift_reg |
顺序赋值 a=b;c=d; / 循环操作 |
并行更新 ↔ 软件顺序执行 |
| 逻辑反转 /高低有效 | ~signal / rst_n |
signal ^=1 / if(!rst_n) |
逻辑翻转 / 低有效信号 |
| 变量 /寄存器 | reg [7:0] data; / wire [7:0] addr; |
int data; / uint8_t addr; |
存储元素 / 信号对应变量 |
| 模块 /函数 | module {...} |
function() {...} |
硬件模块 ↔ 软件函数 |
Protothread
一段c能机械的转换成hdl,一段hdl也能机械的转换成c
c
#include <ap_int.h>
#include <stdint.h>
#ifndef __PROTOTHREAD_H__
#define __PROTOTHREAD_H__
//1ms的时钟周期数
#define PT_THREAD_TICK_MS 27000
#define PT_IN_DATA_W 1
#define PT_OUT_DATA_W 1
class Protothread;
typedef void (*PtRunFun)(Protothread * pt);
class Protothread
{
public:
Protothread(){m_delay = 0; m_state=0;m_next_state=0;m_i=0;}
void Restart() { _ptLine = 0; }
void Stop() { _ptLine = LineNumberInvalid; }
bool IsRunning() { return _ptLine != LineNumberInvalid; }
void PtOsDelay(uint32_t tick){m_delay=tick;}
void PtOsDelayMs(uint32_t ms){m_delay=ms*PT_THREAD_TICK_MS;}
bool Run(){return true;}
protected:
uint32_t m_delay;
typedef unsigned short LineNumber;
static const LineNumber LineNumberInvalid = (LineNumber)(-1);
LineNumber _ptLine;
public:
uint8_t m_i;
uint8_t m_state;
uint8_t m_next_state;
ap_uint<PT_IN_DATA_W> m_indata;
ap_uint<PT_OUT_DATA_W> m_outdata;
};
#define PT_BEGIN() bool ptYielded = true; (void) ptYielded; switch (_ptLine) { case 0:
#define PT_END() default: ; } Stop(); return false;
#define PT_WAIT_UNTIL(condition) \
do { _ptLine = __LINE__; case __LINE__: \
if (!(condition)) return true; } while (0)
#define PT_WAIT_WHILE(condition) PT_WAIT_UNTIL(!(condition))
#define PT_WAIT_THREAD(child) PT_WAIT_WHILE((child).Run())
#define PT_SPAWN(child) \
do { (child).Restart(); PT_WAIT_THREAD(child); } while (0)
#define PT_RESTART() do { Restart(); return true; } while (0)
#define PT_EXIT() do { Stop(); return false; } while (0)
#define PT_YIELD() \
do { ptYielded = false; _ptLine = __LINE__; case __LINE__: \
if (!ptYielded) return true; } while (0)
#define PT_YIELD_UNTIL(condition) \
do { ptYielded = false; _ptLine = __LINE__; case __LINE__: \
if (!ptYielded || !(condition)) return true; } while (0)
#define PT_DELAY(v) \
do { \
m_delay = v; \
PT_WAIT_UNTIL(m_delay == 0); \
} while(0)
#define PT_DELAY_MS(v) \
do { \
m_delay = v*PT_THREAD_TICK_MS; \
PT_WAIT_UNTIL(m_delay == 0); \
} while(0)
#define WHILE(a) PT_BEGIN(); \
while(1)
#define __ON_TICK__ void OnTick(){ if(m_delay==0){Run();}else{m_delay--;}}
#endif
c
#include "Protothread.h"
class LedPt0 : public Protothread {
public: __ON_TICK__
bool Run() {
WHILE(1) {
PT_DELAY_MS(10);
m_outdata=1^m_outdata;
PT_DELAY_MS(15);
m_outdata=1^m_outdata;
PT_DELAY_MS(20);
m_outdata=1^m_outdata;
PT_DELAY_MS(25);
m_outdata=1^m_outdata;
PT_DELAY_MS(30);
m_outdata=1^m_outdata;
PT_DELAY_MS(35);
m_outdata=1^m_outdata;
}
PT_END();
}
};
class LedPt1 : public Protothread {
public: __ON_TICK__
bool Run() {
// 延时1s
PtOsDelayMs(1000);
//按下闪,松开灭
if(m_indata==0){
m_outdata=1^m_outdata;
}else{
m_outdata=1;
}
return 0;
}
};
void my_led_key(
ap_uint<1> key, // 按键输入(低有效)
ap_uint<2> *led, // LED 输出
){
#pragma HLS INTERFACE ap_none port=key
#pragma HLS INTERFACE ap_none port=led
#pragma HLS INTERFACE ap_ctrl_none port=return
static LedPt0 ledPt0;
static LedPt1 ledPt1;
ledPt0.m_indata=key;
ledPt1.m_indata=key;
ledPt0.OnTick();
ledPt1.OnTick();
*led = ledPt1.m_outdata *2 + ledPt0.m_outdata;
}