1.例化
module top;
wire [15:0] btm_a;
wire [ 7:0] btm_b;
wire [ 3:0] btm_c;
wire [ 3:0] btm_y;
wire btm_z;
bottom #(
.A_WIDTH (16),
.B_WIDTH ( 7),
.Y_WIDTH ( 3)
)
inst_btm(
.a (btm_a), //I
.b (btm_b), //I
.c (btm_c), //I
.y (btm_y), //O
.z (btm_z) //O
);
endmodule
module bottom #
(
parameter A_WIDTH = 8,
parameter B_WIDTH = 4,
parameter Y_WIDTH = 2
)
(
input wire [A_WIDTH-1:0] a,
input wire [B_WIDTH-1:0] b,
input wire [ 3:0] c,
output wire [Y_WIDTH-1:0] y,
output reg z
);
// internal logic
endmodule
2.逻辑操作
module bit_logic(
input [31:0] a,
input [31:0] b,
output [31:0] y1,
output [31:0] y2,
output [31:0] y3,
output [31:0] y4,
output [31:0] y5,
output [31:0] y6,
output [31:0] y7
);
assign y1 = a & b; //与
assign y2 = a | b; //或
assign y3 = ~a; //非
assign y4 = ~(a & b); //与非
assign y5 = ~(a | b); //或非
assign y6 = a ^ b; //异或
assign y7 = a ~^ b; //同或
endmodule
//ALU
3.译码器
//使用数据流描述
module decoder(
input [4:0] i_addr,
input i_req,
output [1:0] o_addr,
output [7:0] o_req
);
wire [2:0] dec_addr;
assign dec_addr = i_addr[4:2];
// address decoding
assign o_req[0] = i_req && (dec_addr == 'd0);
assign o_req[1] = i_req && (dec_addr == 'd1);
assign o_req[2] = i_req && (dec_addr == 'd2);
assign o_req[3] = i_req && (dec_addr == 'd3);
assign o_req[4] = i_req && (dec_addr == 'd4);
assign o_req[5] = i_req && (dec_addr == 'd5);
assign o_req[6] = i_req && (dec_addr == 'd6);
assign o_req[7] = i_req && (dec_addr == 'd7);
// offset address
assign o_addr = i_addr[1:0];
endmodule
//使用行为描述
module dec(
input [4:0] i_addr,
input i_req,
output [1:0] o_addr,
output reg [7:0] o_req
);
// address decoding
always @(*) begin
if(i_req)
case (i_addr[4:0])
'd0: o_req = 8'b0000_0001;
'd1: o_req = 8'b0000_0010;
'd2: o_req = 8'b0000_0100;
'd3: o_req = 8'b0000_1000;
'd4: o_req = 8'b0001_0000;
'd5: o_req = 8'b0010_0000;
'd6: o_req = 8'b0100_0000;
'd7: o_req = 8'b1000_0000;
endcase
else
o_req = 'b0;
end
// offset address
assign o_addr = i_addr[1:0];
endmodule
//用generate语句改善编码效率
module decoder_5_32(
input [ 4:0] in,
output [31:0] out
);
genvar i;
generate for (i=0; i<32; i=i+1) begin : gen_for_dec_5_32
assign out[i] = (in == i);
end endgenerate
endmodule
module decoder_6_64(
input [ 5:0] in,
output [63:0] out
);
genvar i;
generate for (i=0; i<63; i=i+1) begin : gen_for_dec_6_64
assign out[i] = (in == i);
end endgenerate
endmodule
4.线性序列机
线性序列机是用来产生无周期的信号的一种方法,与有限状态机产生这种信号相比更简单。设计的基本思路是用计数器对时钟周期个数计数,根据相应时钟下的单个周期时间和计数个数确定某个时刻的时间,确定时间后在需要的时间点转换电平
需要注意的是,这种设计本质上是一种隐式状态机,在代码的可读性上会较差,并不推荐使用
//线性序列机
module line_state(
input clk,
input rst_n,
output reg out
);
//============================================
reg [9:0] cnt;
wire add_cnt;
wire end_cnt;
//============================================
always @(posedge clk, negedge rst_n) begin
if(!rst_n) begin
cnt <= 10'd0;
end
else
if(add_cnt) begin
if(end_cnt) begin
cnt <= 10'd0;
end
else
cnt <= cnt + 1'b1;
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == 1000-1;
//============================================
always @(posedge clk, negedge rst_n) begin
if(!rst_n) begin
out <= 1'b0;
end
else
case(cnt)
0 : out <= 1'b0;
10 : out <= 1'b1;
25 : out <= 1'b0;
100: out <= 1'b1;
125: out <= 1'b0;
300: out <= 1'b1;
410: out <= 1'b0;
456: out <= 1'b1;
500: out <= 1'b0;
510: out <= 1'b1;
560: out <= 1'b0;
600: out <= 1'b1;
630: out <= 1'b0;
670: out <= 1'b1;
800: out <= 1'b0;
850: out <= 1'b1;
900: out <= 1'b0;
910: out <= 1'b1;
950: out <= 1'b0;
990: out <= 1'b1;
endcase
end
endmodule
5.编码器
module encoder_8_3(
input [7:0] in,
output [2:0] out
);
assign out = in[0] ? 3’d0 :
in[1] ? 3’d1 :
in[2] ? 3’d2 :
in[3] ? 3’d3 :
in[4] ? 3’d4 :
in[5] ? 3’d5 :
in[6] ? 3’d6 :
3’d7 ;
endmodule
//这其实是一个优先级编码器
//保证设计输入in永远至多只有一个1
//即at-most-1-hot向量
module encoder_8_3(
input [7:0] in,
output [2:0] out
);
assign out = ({3{in[0]}} & 3’d0)
| ({3{in[1]}} & 3’d1)
| ({3{in[2]}} & 3’d2)
| ({3{in[3]}} & 3’d3)
| ({3{in[4]}} & 3’d4)
| ({3{in[5]}} & 3’d5)
| ({3{in[6]}} & 3’d6)
| ({3{in[7]}} & 3’d7);
endmodule
// input: 8'b01000000
// {3{in[6]}} = 3'b111
// {3{in[6]}} & 3'd7 = 3'd7;
6.数据选择器
module mux5_8b(
input [7:0] in0, in1, in2, in3, in4,
input [2:0] sel,
output [7:0] out
);
assign out = (sel==3’d0) ? in0 :
(sel==3’d1) ? in1 :
(sel==3’d2) ? in2 :
(sel==3’d3) ? in3 :
(sel==3’d4) ? in4 :
8’b0;
endmodule
module mux5_8b(
input [7:0] in0, in1, in2, in3, in4,
input [2:0] sel,
output [7:0] out
);
assign out = ({8{sel==3’d0}} & in0)
| ({8{sel==3’d1}} & in1)
| ({8{sel==3’d2}} & in2)
| ({8{sel==3’d3}} & in3)
| ({8{sel==3’d4}} & in4);
endmodule
//不要忘了写{8{}}中的8
7.寄存器堆
module regfile(
input clk,
// READ PORT 1
input [ 4:0] raddr1,
output [31:0] rdata1,
// READ PORT 2
input [ 4:0] raddr2,
output [31:0] rdata2,
// WRITE PORT
input we, //write enable, HIGH valid
input [ 4:0] waddr,
input [31:0] wdata
);
reg [31:0] rf[31:0];
//WRITE
always @(posedge clk) begin
if (we) rf[waddr]<= wdata;
end
//READ OUT 1
assign rdata1 = (raddr1==5'b0) ? 32'b0 : rf[raddr1];
//READ OUT 2
assign rdata2 = (raddr2==5'b0) ? 32'b0 : rf[raddr2];
endmodule
module regfile(
input clk,
// READ PORT 1
input [ 4:0] raddr1,
output [31:0] rdata1,
// READ PORT 2
input [ 4:0] raddr2,
output [31:0] rdata2,
// WRITE PORT
input we, //write enable, HIGH valid
input [ 4:0] waddr,
input [31:0] wdata
);
reg [31:0] rf[31:0];
wire [31:0] waddr_dec, raddr1_dec, raddr2_dec;
//WRITE
decoder_5_32 U0(.in(waddr ), .out(waddr_dec));
always @(posedge clk) begin
if (we & waddr_dec[ 0]) rf[ 0] <= wdata;
if (we & waddr_dec[ 1]) rf[ 1] <= wdata;
if (we & waddr_dec[ 2]) rf[ 2] <= wdata;
if (we & waddr_dec[ 3]) rf[ 3] <= wdata;
if (we & waddr_dec[ 4]) rf[ 4] <= wdata;
if (we & waddr_dec[ 5]) rf[ 5] <= wdata;
if (we & waddr_dec[ 6]) rf[ 6] <= wdata;
if (we & waddr_dec[ 7]) rf[ 7] <= wdata;
if (we & waddr_dec[ 8]) rf[ 8] <= wdata;
if (we & waddr_dec[ 9]) rf[ 9] <= wdata;
if (we & waddr_dec[10]) rf[10] <= wdata;
if (we & waddr_dec[11]) rf[11] <= wdata;
if (we & waddr_dec[12]) rf[12] <= wdata;
if (we & waddr_dec[13]) rf[13] <= wdata;
if (we & waddr_dec[14]) rf[14] <= wdata;
if (we & waddr_dec[15]) rf[15] <= wdata;
if (we & waddr_dec[16]) rf[16] <= wdata;
if (we & waddr_dec[17]) rf[17] <= wdata;
if (we & waddr_dec[18]) rf[18] <= wdata;
if (we & waddr_dec[19]) rf[19] <= wdata;
if (we & waddr_dec[20]) rf[20] <= wdata;
if (we & waddr_dec[21]) rf[21] <= wdata;
if (we & waddr_dec[22]) rf[22] <= wdata;
if (we & waddr_dec[23]) rf[23] <= wdata;
if (we & waddr_dec[24]) rf[24] <= wdata;
if (we & waddr_dec[25]) rf[25] <= wdata;
if (we & waddr_dec[26]) rf[26] <= wdata;
if (we & waddr_dec[27]) rf[27] <= wdata;
if (we & waddr_dec[28]) rf[28] <= wdata;
if (we & waddr_dec[29]) rf[29] <= wdata;
if (we & waddr_dec[30]) rf[30] <= wdata;
if (we & waddr_dec[31]) rf[31] <= wdata;
end
//READ OUT 1
decoder_5_32 U1(.in(raddr1), .out(raddr1_dec));
assign rdata1 = ({32{raddr1_dec[ 1]}} & rf[ 1]) //NOTE: we omit No. 0 entry because GR[0] always be zero.
| ({32{raddr1_dec[ 2]}} & rf[ 2])
| ({32{raddr1_dec[ 3]}} & rf[ 3])
| ({32{raddr1_dec[ 4]}} & rf[ 4])
| ({32{raddr1_dec[ 5]}} & rf[ 5])
| ({32{raddr1_dec[ 6]}} & rf[ 6])
| ({32{raddr1_dec[ 7]}} & rf[ 7])
| ({32{raddr1_dec[ 8]}} & rf[ 8])
| ({32{raddr1_dec[ 9]}} & rf[ 9])
| ({32{raddr1_dec[10]}} & rf[10])
| ({32{raddr1_dec[11]}} & rf[11])
| ({32{raddr1_dec[12]}} & rf[12])
| ({32{raddr1_dec[13]}} & rf[13])
| ({32{raddr1_dec[14]}} & rf[14])
| ({32{raddr1_dec[15]}} & rf[15])
| ({32{raddr1_dec[16]}} & rf[16])
| ({32{raddr1_dec[17]}} & rf[17])
| ({32{raddr1_dec[18]}} & rf[18])
| ({32{raddr1_dec[19]}} & rf[19])
| ({32{raddr1_dec[20]}} & rf[20])
| ({32{raddr1_dec[21]}} & rf[21])
| ({32{raddr1_dec[22]}} & rf[22])
| ({32{raddr1_dec[23]}} & rf[23])
| ({32{raddr1_dec[24]}} & rf[24])
| ({32{raddr1_dec[25]}} & rf[25])
| ({32{raddr1_dec[26]}} & rf[26])
| ({32{raddr1_dec[27]}} & rf[27])
| ({32{raddr1_dec[28]}} & rf[28])
| ({32{raddr1_dec[29]}} & rf[29])
| ({32{raddr1_dec[30]}} & rf[30])
| ({32{raddr1_dec[31]}} & rf[31]);
//READ OUT 2
decoder_5_32 U2(.in(raddr2), .out(raddr2_dec));
assign rdata2 = ({32{raddr2_dec[ 1]}} & rf[ 1])
| ({32{raddr2_dec[ 2]}} & rf[ 2])
| ({32{raddr2_dec[ 3]}} & rf[ 3])
| ({32{raddr2_dec[ 4]}} & rf[ 4])
| ({32{raddr2_dec[ 5]}} & rf[ 5])
| ({32{raddr2_dec[ 6]}} & rf[ 6])
| ({32{raddr2_dec[ 7]}} & rf[ 7])
| ({32{raddr2_dec[ 8]}} & rf[ 8])
| ({32{raddr2_dec[ 9]}} & rf[ 9])
| ({32{raddr2_dec[10]}} & rf[10])
| ({32{raddr2_dec[11]}} & rf[11])
| ({32{raddr2_dec[12]}} & rf[12])
| ({32{raddr2_dec[13]}} & rf[13])
| ({32{raddr2_dec[14]}} & rf[14])
| ({32{raddr2_dec[15]}} & rf[15])
| ({32{raddr2_dec[16]}} & rf[16])
| ({32{raddr2_dec[17]}} & rf[17])
| ({32{raddr2_dec[18]}} & rf[18])
| ({32{raddr2_dec[19]}} & rf[19])
| ({32{raddr2_dec[20]}} & rf[20])
| ({32{raddr2_dec[21]}} & rf[21])
| ({32{raddr2_dec[22]}} & rf[22])
| ({32{raddr2_dec[23]}} & rf[23])
| ({32{raddr2_dec[24]}} & rf[24])
| ({32{raddr2_dec[25]}} & rf[25])
| ({32{raddr2_dec[26]}} & rf[26])
| ({32{raddr2_dec[27]}} & rf[27])
| ({32{raddr2_dec[28]}} & rf[28])
| ({32{raddr2_dec[29]}} & rf[29])
| ({32{raddr2_dec[30]}} & rf[30])
| ({32{raddr2_dec[31]}} & rf[31]);
endmodule
Comments | NOTHING