&& (timer >= 32'd149_999_999) ) ? 4'b1111 :
// 占空比 1/16 = 6.25%
( led_mode[3] && (timer >= 32'd129_999_999) && (timer[3:0] == 4'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd129_999_999) ) ? 4'b1111 :
// 占空比 1/8 = 12.5%
( led_mode[3] && (timer >= 32'd109_999_999) && (timer[2:0] == 3'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd109_999_999) ) ? 4'b1111 :
// 占空比 1/4 = 25%
( led_mode[3] && (timer >= 32'd89_999_999 ) && (timer[1:0] == 2'b00 ) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd89_999_999 ) ) ? 4'b1111 :
// 12.5%
( led_mode[3] && (timer >= 32'd69_999_999 ) && (timer[2:0] == 3'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd69_999_999 ) ) ? 4'b1111 :
// 6.25%
( led_mode[3] && (timer >= 32'd49_999_999 ) && (timer[3:0] == 4'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd49_999_999 ) ) ? 4'b1111 :
// 3.12%
( led_mode[3] && (timer >= 32'd29_999_999 ) && (timer[4:0] == 5'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd29_999_999 ) ) ? 4'b1111 :
// 1.56%
( led_mode[3] && (timer >= 32'd9_999_999 ) && (timer[5:0] == 6'b000) ) ? 4'b0000 :
( led_mode[3] && (timer >= 32'd9_999_999 ) ) ? 4'b1111 :
// 0%
( led_mode[3] ) ? 4'b1111 :
....(其他模式)
可以看出上述代码实现了占空比从0% → 1.56% → 3.12% → 6.25% → 12.5% → 25% → 12.5% → 6.25% → 3.12% → 1.56% → 0%的等时间间隔变化,
由于开发板LED灯功率较高,在25%到100%之间的占空比,LED灯亮度都会很高,看不出太大变化,
因此我们将25%设定为了最高的占空比,对应LED灯最亮的时刻。
Control Unit模块的完整RTL如下:
module AHB_control_unit #(
//AHB Parameters
parameter OKAY = 2'b00 ,
parameter ERROR = 2'b01 ,
parameter SPLIT = 2'b10 ,
parameter RETRY = 2'b11 ,
parameter IDLE = 2'b00 ,
parameter BUSY = 2'b01 ,
parameter SEQ = 2'b10 ,
parameter NONSEQ = 2'b11 ,
parameter BYTE = 3'b000 ,
parameter WORD = 3'b001 ,
parameter DWORD = 3'b010 ,
parameter SINGLE = 3'b000 ,
parameter INCR = 3'b001 ,
parameter WRAP4 = 3'b010 ,
parameter INCR4 = 3'b011 ,
parameter WARP8 = 3'b100 ,
parameter INCR8 = 3'b101 ,
parameter WARP16 = 3'b110 ,
parameter INCR16 = 3'b111 ,
//Control Unit FSM Parameters
parameter CONFIG_0 = 3'b000,
parameter CONFIG_1 = 3'b001,
parameter CONFIG_2 = 3'b010,
parameter READ_DATA_RO = 3'b011,
parameter WRITE_DATA_0 = 3'b100,
parameter WRITE_DATA_1 = 3'b101,
parameter WRITE_DATA_2 = 3'b110,
parameter WRITE_DATA_3 = 3'b111,
// LED_mode Parameters
parameter MODE0 = 4'b0001,
parameter MODE1 = 4'b0010,
parameter MODE2 = 4'b0100,
parameter MODE3 = 4'b1000,
//Address Parameters
parameter ADDR_GPIO = 32'h0000_0000,
parameter OFFSET_GPIO_DATA_RO = 4'h0,
parameter OFFSET_GPIO_DATA = 4'h4,
parameter OFFSET_GPIO_DIRM = 4'h8,
parameter OFFSET_GPIO_OEN = 4'hC
) (
// Input from AHB Bus
input iHCLK,
input iHRESETn,
input iHREADY,
input [1:0] iHRESP,
input [31:0] iHRDATA,
// Output to AHB Bus
output [1:0] oHTRANS,
output [2:0] oHSIZE,
output [2:0] oHBURST,
output oHWRITE,
output [31:0] oHADDR ,
output [31:0] oHWDATA
);
/*————————————————————————————————————————————————————————————————————————*\
/ Control Unit FSM \
\*————————————————————————————————————————————————————————————————————————*/
reg [2:0] CU_state;
always @(posedge iHCLK ) begin
if ( !iHRESETn ) begin
CU_state <= CONFIG_0;
end else begin
case (CU_state)
// write GPIO_DIRM
CONFIG_0: begin
if ( iHREADY ) begin
CU_state <= CO