1 / 51

AHDL 培训教材

AHDL 培训教材. Danny Mok Altera HK FAE (dmok@altera.com). 什么是 AHDL?. AHDL 是 A ltera H ardware D escription L anguage 的缩写 由 Altera 公司开发 集成在 Altera 的开发软件 Max+Plus II 中 以语言的形式而不是图形的形式描述硬件 容易修改 容易维护 尤其适合实现以下的逻辑功能 复杂的组合逻辑 BCD 码向 7 段字形的转换器 状态机 地址译码 其他你还没想到的功能……. 接上页. 与图形输入方式一样容易

reid
Download Presentation

AHDL 培训教材

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. AHDL培训教材 Danny Mok Altera HK FAE (dmok@altera.com)

  2. 什么是 AHDL? • AHDL是Altera Hardware Description Language的缩写 • 由 Altera公司开发 • 集成在 Altera的开发软件Max+Plus II中 • 以语言的形式而不是图形的形式描述硬件 • 容易修改 • 容易维护 • 尤其适合实现以下的逻辑功能 • 复杂的组合逻辑 • BCD码向 7段字形的转换器 • 状态机 • 地址译码 • 其他你还没想到的功能……..

  3. 接上页 • 与图形输入方式一样容易 • 功能与其他硬件描述语言( HDL)同样强大 • 如:标准VHDL、 Verilog HDL 等

  4. 怎样使用 ADHL? 点击这 个按钮 输入你的 AHDL设计文件 • 使用任何一个文本编辑器创建设计文件 • Altera的开发软件Max+Plus II 也提供了一个文本编辑器

  5. 接上页 • 创建 AHDL文件

  6. 接上页 两者必 须相同 • 把你的 ADHL保存为 name.TDF的形式

  7. 接上页 点击这 个图标

  8. 编译过程中的错误定位 错误 定位 点击错 误消息 点击定位按钮 • 错误定位容易

  9. AHDL模板 If-then-else case-end case loop-end loop ??…??? 忘了怎么办? 修改代码

  10. 一般的AHDL文件格式 SUBDESIGN decode1 (input_pin_name :INPUT; input_bus_name[15..0] :INPUT; output_pin_name :OUTPUT; output_bus_name : OUTPUT; ) BEGIN ouptut_pin_name = input_pin_name; output_bus_name = input_bus_name; END; 定义I/O端口 逻辑表达式 AHDL格式 关键字

  11. 第一个 AHDL设计-地址译码器 SUBDESIGN decode1 ( a[3..0] : input; chip_enable : output; ) begin chip_enable = (a[3..0] == H"7"); end; Chip_enable = a0 & a1 & a2 & !a3

  12. 为什么使用 AHDL 而不用图形输入方式 SUBDESIGN decode1 ( a[3..0] : input; chip_enable : output; ) begin chip_enable = (a[3..0] == H"A"); end; Chip_enable = !a0 & a1 & !a2 & a3 修改更麻烦 编译器自己解释函数 只需修改一个字母 • 容易修改 • 输入代码和证实逻辑同时进行 • 将译码输出条件由H”7” 改为H”A”

  13. 更多的优势 比较器的某些输入比特可以忽略 SUBDESIGN decode1 ( a[3..0] : input; chip_enable : output; ) begin chip_enable = (a[3..0] == B"1x0x"); end;

  14. AHDL基本知识 • “加”运算符: + • “减”运算符: - • 数量“相等”运算符: == • “不等”运算符: != • “大于”运算符: > • “大于或等于”运算符: >= • “小于”运算符: < • “小于或等于”运算符: <= • 逻辑“或”运算符: # • 逻辑“逻辑与”运算符: &

  15. 使用常数(Constant)功能 修改一处即可修 改整个设计文件 • 如果文件中相同的数字、字符串或者算术表达式重复出现多次,使用常数(Constant)来表示它们 • 优点 • 如果修改,只需改变一个声明 CONSTANTIO_ADDRESS = H"A"; SUBDESIGN decode1 ( a[3..0] : input; chip_enable : output; ) begin chip_enable = (a[3..0] == IO_ADDRESS); if (a[3..0] == IO_ADDRESS) then ……... end; 在关键字 SUBDESIGN 之前,定义常数 ( CONSTANT)

  16. 常数( Constant)的其他用途 定义一个常数值 定义一个算术表达式 通过预先定义的常数 定义新的常数 • 常数使用举例 Constant IO_ADDRESS = H”370”; Constant FOO = 1+2*3 - LOG2(256); Constant FOO_PLUS_one = FOO + 1;

  17. 组合逻辑的实现 图形设计文件 AHDL设计文件 SUBSDESIGN decode1 ( a0, a1, b : input; out1, out2 : output; ) begin out1 = a0 & !a1; out2 = out1 # b; end; out1 = a0 & !a1 out2 = a0 & !a1 # b

  18. 定义节点 图形方式 AHDL 方式 temp SUBDESIGN decode1 ( a0, a1, b, d: input; out2, out3 : output; ) variable temp : node; begin temp = a0 & !a1; out2 = temp # b; out3 = temp & d; end; out2 = a0 & !a1 # b out3 = a0 & !a1 & d

  19. 总线操作 功能相同 但容易描述 SUBDESIGN decode1 ( a[3..0], b[3..0] : input; out[3..0]: output; ) begin out1[] = a[] & b[]; end; SUBDESIGN decode1 ( a[3..0], b[3..0] : input; out[3..0] : output; ) begin out0 = a0 & b0; out1 = a1 & b1; out2 = a2 & b2; out3 = a3 & b3; end;

  20. 总线操作的其他方式 总线操作 a[9..0], b[9..0] • a[] = b[]; • a[7..4] = b[9..6]; • a[9..8] = VCC; • a[9..8] = 1; • a[9..8] = 2; • a[9..8] = 3; • a[3..0] = GND • a[3..0] = 0; • temp = b0& b1; a[2..1] = temp a7=b9, a6=b8, a5=b7, a4=b6 a[9..8] connect to VCC a[9..8] = B”01” a[9..8] = B”10” a[9..8] = B”11” a[3..0] connect to GND a[3..0] = B”0000” a2 = temp, a1 = temp

  21. 高级总线操作 a[3..2][1..0] = b[]; 首先对低位比特赋值 a3_1 = b3 a3_0 = b2 a2_1 = b1 a2_0 = b0 • 总线 • b[3..0] • b3, b2, b1, b0 (having 4 members) • MSB is b3, LSB is b0 • 总线阵列 • a[3..0][2..0] • a3_2, a3_1, a3_0, a2_2, a2_1, a2_0, a1_2, a1_1, a1_0, a0_2, a0_1, a0_0 (having 12 members) • MSB is a3_2, LSB is a0_0

  22. i[3..0] Segment 7 0 0 1 1 2 2 F F 真值表 a b f g c e d 修改非常方便

  23. IF-THEN-ELSE语句 SUBDESIGN priority ( low, medium, high : input; highest_level[3..0] : output; ) begin if ( high == B”1”) then highest_level[] = B”1000”; elsif (medium == B”1”) then highest_level[] = B”0100”; elsif (low == B”1”) then highest_level[] = B”0010”; else highest_level[] = B”0001”; end if; end;

  24. 需要4个逻辑单元

  25. CASE语句 SUBDESIGN decoder (low, medium, high : input; highest_level[3..0] : output; ) variable code[2..0] : node; begin code2=high; code1=medium; code0=low; case code[] is when 4 => highest_level[] = B”1000”; when 2 => highest_level[] = B”0100”; when 1 => highest_level[] = B”0010”; when others => highest_level[] = B”0001”; end case; end; 注意这一行的用法

  26. 循环语句FOR...LOOP... CONSTANT num_of_bit = 8; SUBDESIGN numbit ( a[num_of_bit..0] : input; b[num_of_bit..0] : output; ) begin fori in 0 to num_of_bitgenerate b[num_of_bit - i] = a[i]; end generate; end; CONSTANT num_of_bit = 8; SUBDESIGN numbit ( a[num_of_bit..0] : input; b[num_of_bit..0] : output; ) begin b[8] = a[0]; b[7] = a[1]; b[6] = a[2]; b[5] = a[3]; b[4] = a[4]; b[3] = a[5]; b[2] = a[6]; b[1] = a[7]; b[0] = a[8]; end; 实现相同的功能更加容易 CONSTANT num_of_bit = 8; SUBDESIGN numbit (a[num_of_bit..0] : input; b[num_of_bit..0] : otuput; ) begin b[num_of_bit..0] = a[0..num_of_bit]; end;

  27. 用图形方式调用AHDL • 使用文件菜单的“Create Default Symbol”条目为 AHDL 设计创建默认符号 • 在图形输入中使用这个默认符号

  28. 寄存器逻辑的实现 方法 2 方法 1 SUBDESIGN flip_flop ( d, clk : input; q : output;) variable temp : dff; begin temp.d = d; temp.clk = clk; q = temp.q; end; SUBDESIGN flip_flop ( d, clk : input; q : output;) begin q = dff(d,clk, ,); end; 调用一个 D-Flipflop

  29. 更详细的说明

  30. 关于寄存器的其他问题 • 如何实现总线寄存器 • 其他类型的寄存器的应用 • DFFE: 带使能端的D触发器 • TFF/TFFE:T触发器和带使能端的T触发器 • JKFF/JKFFE :JK触发器和带使能端的JK触发器 • SRFF/SRFFE:SR触发器和带使能端的SR触发器

  31. 总线寄存器的实现 SUBDESIGN bus_reg ( clk, d[7..0] : input; q[7..0] : output; ) variable ff[7..0] : dff; begin ff[].clk = clk; ff[].d = d[]; q[] = ff[].q; end; ff[0].clk = clk; ff[1].clk = clk; ff[2].clk = clk; ff[3].clk = clk; ff[4].clk = clk; ff[5].clk = clk; ff[6].clk = clk; ff[7].clk = clk; ff[0].d = d[0]; ff[1].d = d[1]; ff[2].d = d[2]; ff[3].d = d[3]; ff[4].d = d[4]; ff[5].d = d[5]; ff[6].d = d[6]; ff[7].d = d[7]; q[0] = ff[0].q; q[1] = ff[1].q; q[2] = ff[2].q; q[3] = ff[3].q; q[4] = ff[4].q; q[5] = ff[5].q; q[6] = ff[6].q; q[7] = ff[7].q;

  32. 带清零端、预置端和使能端的D触发器 SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; PRN PRN PRN PRN PRN PRN D D D D D D Q Q Q Q Q Q CLK CLK CLK CLK CLK CLK ENA ENA ENA ENA ENA ENA CLRN CLRN CLRN CLRN CLRN CLRN SUBDESIGN flip_flop_enable ( clock, data, enable, preset, clear : input; qout : output; ) variable temp : dffe; begin temp.d = data; temp.clk = clock; temp.clrn = clear; temp.prn = preset; temp.ena = enable; qout = temp.q; end; PRN Q D CLK ENA CLRN

  33. 其他类型的触发器

  34. 帮助菜单的使用 问:我不知道怎样使用 Altera的D触发器和带使能端的JK触发器,我该怎么办 ? 答:Altera 的帮助菜单是找到答案的好地方 问:怎样使用帮助菜单 ? 答: 很容易而且很有趣 DFFE

  35. 帮助菜单的使用

  36. 三态缓冲器的实现 方法 1 方法 2 SUBDESIGN tri_state ( a, enable : input; b : output;) variable temp : tri; begin temp.in = a; temp.oe = enable; b = temp.out; end; SUBDESIGN tri_state (a, enable : input; b : output;) begin b = tri(a, enable); end;

  37. 更详细的说明

  38. OPNDRN -漏极开路缓冲器 Method 2 Method 1 SUBDESIGN tri_state ( enable : input; b : output;) variable temp : opndrn; begin temp.in= enable; b = temp.out; end; SUBDESIGN opn_drn (enable : input; b : output;) begin b = opndrn(enable); end;

  39. 更详细的说明

  40. 使用 AHDL与使用原理图同样方便但是AHDL功能更强大

  41. 练习部分 AHDL SUBDESIGN tri_io ( clk, enable : input; io : bidir;) variable temp1 : dff; temp2 : tri; begin temp1.d = io; temp1.clk = clk; temp2.in = temp1.q; temp2.oe = enable; io = temp2.out; end; 输入引脚 双向引脚 clk, enable : input; io : bidir;

  42. 轻松地设计一个8位计数器 SUBDESIGN 8bits (clk : input; q[7..0] : output; ) variable temp[7..0] : dff; begin temp[].clk = clk; temp[].d = temp[].q +1 ; q[] = temp[].q; end;

  43. 状态机设计 SUBDESIGN simple ( clk, reset, jump : input; q : output; ) variable ss : MACHINE WITH STATES (S0,S1); begin ss.clk = clk; ss.reset = reset; case ss is when s0 => q = gnd; if (jump) then ss = s1; end if; when s1 => q = vcc; if (jump) then ss = s0; end if; end case; end; 状态转移图 jump=0 q = 0 S0 注 : 所有的状态机都必须受时钟驱动 jump=1 jump=1 S1 q = 1 jump=0

  44. 状态转移波形图 if (jump) then ss = s1; end if; if (jump) then ss = s0; end if;

  45. 状态机设计的其他问题 SUBDESIGN stepper ( reset, ccw, cw, clk : input; phase[3..0] : output;) variable ss : MACHINE OF BITS (temp[3..0]) WITH STATES ( s0 = B”0001”, s1 = B”0010”, s2 = B”0100”, s3 = B”1000”); begin ss.clk = clk; if (reset) then ss = s2; end if; phase[] = temp[]; TABLE ss, ccw, cw => ss; s0, 1, x => s3; s0, x, 1 => s1; s1, 1, x => s0; s1, x, 1 => s2; s2, 1, x => s1; s2, x, 1 => s3; s3, 1, x => s2; s3, x, 1 => s0; END TABLE; end; 注 : 不必对 TEMP进行声明 它会自动声明为D触发器

  46. 状态转移图 用户可以控制初始状态

  47. 练习题 SUBDESIGN stepper ( reset, ccw, cw, clk : input; phase[3..0] : output;) variable ss : MACHINE OF BITS (temp[3..0]) WITH STATES ( s0 = B”0001”, s1 = B”0010”, s2 = B”0100”, s3 = B”1000”); begin ss.clk = clk; if (reset) then ss = s2; end if; phase[] = temp[]; TABLE ss, ccw, cw => ss; s0, 1, x => s3; s0, x, 1 => s1; s1, 1, x => s0; s1, x, 1 => s2; s2, 1, x => s1; s2, x, 1 => s3; s3, 1, x => s2; s3, x, 1 => s0; END TABLE; end; 试着修改CASE语句的真值表

  48. 没有恢复状态的状态机 SUBDESIGN recover ( clk, go : input; ok : output;) variable sequence : MACHINE OF BITS (q[2..0]) with STATES ( idle, one, two, three, four, illegal1, illegal2, illegal3); begin sequence.clk = clk; case sequence is when idle => if (go) then sequence = one; end if; when one => sequence = two; when two => sequence = three; when three => sequence = four; end case; ok = (sequence == four); end; 状态机停留在状态“ FOUR”上面

  49. 状态机最好具有自启动功能 SUBDESIGN recover ( clk, go : input; ok : output;) variable sequence : MACHINE OF BITS (q[2..0]) with STATES ( idle, one, two, three, four, illegal1, illegal2, illegal3); begin sequence.clk = clk; case sequence is when idle => if (go) then sequence = one; end if; when one => sequence = two; when two => sequence = three; when three => sequence = four; when OTHERS => sequence = idle; end case; ok = (sequence == four); end; 三比特实现八个状态 只有五个状态有用时, 最好使用自启动选项

More Related