在设计一个复用器的时候,可以使用时序逻辑去做,即通过if
或者case
语句去比较选择信号的值;也可以通过组合逻辑去做,即真值表的形式。一般来讲,使用组合逻辑去做APB的Slave MUX比较好,因为APB的速度也不是很快,同时也可以少一个clock cycle。
代码:时序逻辑下的MUX设计方法
always @(*) begin if(DECODE4BIT == 0) PRDATA = PRDATA0 else if(DECODE4BIT == 1) PRDATA = PRDATA1 else if(DECODE4BIT == 2) PRDATA = PRDATA2 // 后面略掉 end
always @(*) begin case(DECODE4BIT) 0: PRDATA = PRDATA0 1: PRDATA = PRDATA1 2: PRDATA = PRDATA2 // 后面略掉 end
代码:组合逻辑下PREADY输出信号
assign PREADY = ~PSEL | ( dec[ 0] & (PREADY0 | ~en[ 0]) ) | ( dec[ 1] & (PREADY1 | ~en[ 1]) ) | ( dec[ 2] & (PREADY2 | ~en[ 2]) ) | ( dec[ 3] & (PREADY3 | ~en[ 3]) ) | ( dec[ 4] & (PREADY4 | ~en[ 4]) ) | ( dec[ 5] & (PREADY5 | ~en[ 5]) ) | ( dec[ 6] & (PREADY6 | ~en[ 6]) ) | ( dec[ 7] & (PREADY7 | ~en[ 7]) ) | ( dec[ 8] & (PREADY8 | ~en[ 8]) ) | ( dec[ 9] & (PREADY9 | ~en[ 9]) ) | ( dec[10] & (PREADY10 | ~en[10]) ) | ( dec[11] & (PREADY11 | ~en[11]) ) | ( dec[12] & (PREADY12 | ~en[12]) ) | ( dec[13] & (PREADY13 | ~en[13]) ) | ( dec[14] & (PREADY14 | ~en[14]) ) | ( dec[15] & (PREADY15 | ~en[15]) );
以下是组合逻辑的参考设计。16个slaves,每个slave都会输出pready,prdata,和perror信号。此复用器需要根据选择信号,选择相应slave的pready,prdata,perror信号,送给AHB2APB bridge。
代码:组合逻辑下16个Slave的译码和使能信号的产生
// 根据参数parameter PORTx_ENABLE为每个端口产生一个使能信号 wire [15:0] en = { (PORT15_ENABLE == 1), (PORT14_ENABLE == 1), (PORT13_ENABLE == 1), (PORT12_ENABLE == 1), (PORT11_ENABLE == 1), (PORT10_ENABLE == 1), (PORT9_ENABLE == 1), (PORT8_ENABLE == 1), (PORT7_ENABLE == 1), (PORT6_ENABLE == 1), (PORT5_ENABLE == 1), (PORT4_ENABLE == 1), (PORT3_ENABLE == 1), (PORT2_ENABLE == 1), (PORT1_ENABLE == 1), (PORT0_ENABLE == 1) }; // 在根据DECODE4BIR为每一个端口产生译码信号,只有当DECODE4BIT等于对应端口值的时候,相应的译码信号才为高; // DECODE4BIT[3:0] 为MUX模块的输入信号,如果有16个Slave,那么DECODE4BIT输入可以定义为[3:0]的位宽 wire [15:0] dec = { (DECODE4BIT == 4'd15), (DECODE4BIT == 4'd14), (DECODE4BIT == 4'd13), (DECODE4BIT == 4'd12), (DECODE4BIT == 4'd11), (DECODE4BIT == 4'd10), (DECODE4BIT == 4'd9 ), (DECODE4BIT == 4'd8 ), (DECODE4BIT == 4'd7 ), (DECODE4BIT == 4'd6 ), (DECODE4BIT == 4'd5 ), (DECODE4BIT == 4'd4 ), (DECODE4BIT == 4'd3 ), (DECODE4BIT == 4'd2 ), (DECODE4BIT == 4'd1 ), (DECODE4BIT == 4'd0 ) }; assign PSEL0 = PSEL & dec[ 0] & en[ 0]; assign PSEL1 = PSEL & dec[ 1] & en[ 1]; assign PSEL2 = PSEL & dec[ 2] & en[ 2]; assign PSEL3 = PSEL & dec[ 3] & en[ 3]; assign PSEL4 = PSEL & dec[ 4] & en[ 4]; assign PSEL5 = PSEL & dec[ 5] & en[ 5]; assign PSEL6 = PSEL & dec[ 6] & en[ 6]; assign PSEL7 = PSEL & dec[ 7] & en[ 7]; assign PSEL8 = PSEL & dec[ 8] & en[ 8]; assign PSEL9 = PSEL & dec[ 9] & en[ 9]; assign PSEL10 = PSEL & dec[10] & en[10]; assign PSEL11 = PSEL & dec[11] & en[11]; assign PSEL12 = PSEL & dec[12] & en[12]; assign PSEL13 = PSEL & dec[13] & en[13]; assign PSEL14 = PSEL & dec[14] & en[14]; assign PSEL15 = PSEL & dec[15] & en[15];
代码:组合逻辑下PSLVERR输出信号
assign PSLVERR = ( PSEL0 & PSLVERR0 ) | ( PSEL1 & PSLVERR1 ) | ( PSEL2 & PSLVERR2 ) | ( PSEL3 & PSLVERR3 ) | ( PSEL4 & PSLVERR4 ) | ( PSEL5 & PSLVERR5 ) | ( PSEL6 & PSLVERR6 ) | ( PSEL7 & PSLVERR7 ) | ( PSEL8 & PSLVERR8 ) | ( PSEL9 & PSLVERR9 ) | ( PSEL10 & PSLVERR10 ) | ( PSEL11 & PSLVERR11 ) | ( PSEL12 & PSLVERR12 ) | ( PSEL13 & PSLVERR13 ) | ( PSEL14 & PSLVERR14 ) | ( PSEL15 & PSLVERR15 );
根据下述三个原则,设计PREADY信号。PREADY
的default值应该为1,即使PSEL
为0的时候;当PSEL
为1的时候,根据译码信号dec
选择相应的PREADYx
信号;当端口没有使能的时候en[x] == 0
, 对应的PREADYx
信号不会被选择
代码:组合逻辑下PRDATA输出信号
assign PRDATA = ( {32{PSEL0 }} & PRDATA0 ) | ( {32{PSEL1 }} & PRDATA1 ) | ( {32{PSEL2 }} & PRDATA2 ) | ( {32{PSEL3 }} & PRDATA3 ) | ( {32{PSEL4 }} & PRDATA4 ) | ( {32{PSEL5 }} & PRDATA5 ) | ( {32{PSEL6 }} & PRDATA6 ) | ( {32{PSEL7 }} & PRDATA7 ) | ( {32{PSEL8 }} & PRDATA8 ) | ( {32{PSEL9 }} & PRDATA9 ) | ( {32{PSEL10}} & PRDATA10 ) | ( {32{PSEL11}} & PRDATA11 ) | ( {32{PSEL12}} & PRDATA12 ) | ( {32{PSEL13}} & PRDATA13 ) | ( {32{PSEL14}} & PRDATA14 ) | ( {32{PSEL15}} & PRDATA15 );