基本逻辑电路描述

发布于 2020-12-15  295 次阅读


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


追求理性 独立思考 不做韭菜