单端口寄存器堆


模块框图如下:

设计源码如下:

 1 module Single_port_register_set(
 2     input                               clk         ,
 3     input                               rst_n       ,
 4 
 5     input       [ 1:0]                  index       ,
 6     input                               load        ,
 7     input                               data_in     ,
 8 
 9     output                              Q           
10 );
11 
12 //-----------------------------------------------------------------------------------
13 
14 reg         [ 3:0]                      en          ;
15 reg         [ 3:0]                      q           ;
16 
17 //-----------------------------------------------------------------------------------
18 
19 always @(load or index or rst_n) begin
20     if(rst_n == 1'b0)
21         en = 4'h0;
22     else if(load == 1'b1)begin
23         case(index)
24             2'b00: en = 4'b0001;
25             2'b01: en = 4'b0010;
26             2'b10: en = 4'b0100;
27             2'b11: en = 4'b1000;
28             default: en = 4'b0000;
29         endcase
30     end
31     else
32         en = en;
33 end
34 
35 always @(posedge clk or negedge rst_n) begin
36     if(!rst_n)
37         q <= 4'b0000;
38     else begin
39         case(en)
40             4'b0001: q[0] <= data_in;
41             4'b0010: q[1] <= data_in;
42             4'b0100: q[2] <= data_in;
43             4'b1000: q[3] <= data_in;
44             default: q    <= 4'b0000;
45         endcase
46     end
47 end
48 
49 always @(index) begin
50     if(!rst_n)
51         Q <= 1'b0;
52     else begin
53         case(index)
54             2'b00: Q <= q[0];
55             2'b01: Q <= q[1];
56             2'b10: Q <= q[2];
57             2'b11: Q <= q[3];
58             default: Q <= 1'b0;
59         endcase
60     end
61 end
62 
63 endmodule

三端口寄存器堆框图:

设计源码如下:

 1 module Three_port_register_set(
 2     input                               clk         ,
 3     input                               rst_n       ,
 4 
 5     input   [1:0]                       wr_addr     ,
 6     input                               wr_data     ,
 7     input                               wr_en       ,
 8 
 9     input   [1:0]                       rd_addr1    ,
10     input   [1:0]                       rd_addr2    ,
11 
12     output                              rd_data1    ,
13     output                              rd_data2
14 );
15 
16 //-----------------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------------
18 
19 reg             [3:0]                   en          ;
20 reg             [3:0]                   q           ;
21 
22 //-----------------------------------------------------------------------------------
23 //-----------------------------------------------------------------------------------
24 
25 always @(*) begin
26     if(!rst_n)
27         en = 4'b0000;
28     else if(wr_en == 1'b1) begin
29         case(wr_addr)
30             2'b00: en = 4'b0000; //------
31             2'b01: en = 4'b0010;
32             2'b10: en = 4'b0100;
33             2'b11: en = 4'b1000;
34             default: en = 4'b0000;
35         endcase
36     end
37     else
38         en = en;
39 end
40 
41 always @(posedge clk or negedge rst_n) begin
42     if(!rst_n)
43         q <= 4'b0000;
44     else begin
45         case(en)
46             4'b0001: q[0] <= wr_data; //------
47             4'b0010: q[1] <= wr_data;
48             4'b0100: q[2] <= wr_data;
49             4'b1000: q[3] <= wr_data;
50             default: q    <= 4'b0000;
51         endcase
52     end
53 end
54 
55 always @(rd_addr1 or rst_n or q) begin
56     if(!rst_n)
57         rd_data1 <= 1'b0;
58     else begin
59         case(rd_addr1)
60             2'b00: rd_data1 <= q[0];
61             2'b01: rd_data1 <= q[1];
62             2'b10: rd_data1 <= q[2];
63             2'b11: rd_data1 <= q[3];
64             default: rd_data1 <= 1'b0;
65         endcase
66     end
67 end
68 
69 always @(rd_addr2 or rst_n or q) begin
70     if(!rst_n)
71         rd_data2 <= 1'b0;
72     else begin
73         case(rd_addr2)
74             2'b00: rd_data2 <= q[0];
75             2'b01: rd_data2 <= q[1];
76             2'b10: rd_data2 <= q[2];
77             2'b11: rd_data2 <= q[3];
78             default: rd_data2 <= 1'b0;
79         endcase
80     end
81 end
82 
83 endmodule