Altifigence Academy

56 / 63 · Khái niệm

Tập thanh ghi hai cổng đọc, một cổng ghi và bypass

Hiện thực hai cổng đọc độc lập và ghi đồng bộ; kiểm tra bypass theo từng xung đột địa chỉ cùng chính sách khởi tạo và valid.

Bộ nhớ lấy đồng thời hai giá trị

Để tính A+B trong khối số học, cần hai toán hạng ở cùng chu kỳ. Tập thanh ghiThanh ghi Mạch lưu trạng thái nhiều bit. Thanh ghi đồng bộ trong khóa học lưu đầu vào đã quy định tại cạnh clock. Tìm hiểu thêm 2-read/1-write cung cấp hai địa chỉ đọc và một địa chỉ ghi. Ở đây ta lưu 8 từ 16 bit, và cả hai đầu ra đọc đều được chốt tại cạnh lên. Độ rộng địa chỉ là 3 bit, dung lượng là 8×16=128 bit. Địa chỉ 0 cũng là ô lưu thông thường, không có quy tắc thanh ghi hằng đặc biệt.

Mỗi cổng đọc có enable và valid riêng. Một cổng có thể đọc khi cổng kia nghỉ; hai cổng cũng có thể đọc cùng địa chỉ. Khả năng đọc đồng thời hai địa chỉ khác nhau tạo chi phí khác với tăng dung lượng. Mạch nhỏ có thể dùng mảng flip-flopFlip-flop Phần tử lưu đầu vào tại cạnh clock chỉ định rồi giữ đến cạnh sau. Đầu vào phải thỏa setup và hold. Tìm hiểu thêm và hai mạng chọn. Nếu dùng một loại RAM cụ thể, có thể cân nhắc nhân bản bộ nhớ và gửi phép ghi đến mọi bản để có đủ cổng đọc. Chỉ khai báo RTL chưa xác định được tài nguyên mà tổng hợp sẽ dùng.

Khi giá trị đang ghi cũng là giá trị đang đọc

Hợp đồng lần này phản hồi dữ liệu ghi mới khi đọc và ghi cùng địa chỉ ở cùng cạnh. Ta dùng bypass đưa trực tiếp wr_data vào đầu vào của thanh ghi đọc, không chờ mảng lưu cập nhật. Định nghĩa điều kiện xung đột của cổng ii như sau:

Hi=wr_en∧(wr_addr=rd_addri)H_i=\mathrm{wr\_en}\land(\mathrm{wr\_addr}=\mathrm{rd\_addr}_i)

Khi rd_eni=1\mathrm{rd\_en}_i=1, phản hồi là:

Ri+={wr_data,Hi=1M−[rd_addri],Hi=0R_i^{+}=\begin{cases} \mathrm{wr\_data}, & H_i=1\\ M^{-}[\mathrm{rd\_addr}_i], & H_i=0 \end{cases}

M−M^{-} là giá trị lưu ngay trước cạnh. HiH_i so sánh độc lập với từng địa chỉ đọc. Nếu một cổng xung đột mà đưa dữ liệu ghi đến cả hai đầu ra, toán hạng ở địa chỉ khác cũng bị thay đổi. Nếu bỏ wr_en khỏi điều kiện, mạch còn bypass sai trong chu kỳ không ghi chỉ vì wr_addr tình cờ trùng địa chỉ đọc.

SystemVerilog
module regfile8x16_2r1w (
  input  logic        clk, rst, wr_en,
  input  logic [2:0]  wr_addr,
  input  logic [15:0] wr_data,
  input  logic        rd_en0, rd_en1,
  input  logic [2:0]  rd_addr0, rd_addr1,
  output logic [15:0] rd_data0, rd_data1,
  output logic        rd_valid0, rd_valid1
);
  timeunit 1ns;
  timeprecision 1ps;
  logic [15:0] mem [0:7];

  always_ff @(posedge clk) begin
    if (rst) begin
      rd_valid0 <= 1'b0;
      rd_valid1 <= 1'b0;
    end else begin
      rd_valid0 <= rd_en0;
      rd_valid1 <= rd_en1;
      if (wr_en)
        mem[wr_addr] <= wr_data;
      if (rd_en0)
        rd_data0 <= (wr_en && wr_addr == rd_addr0)
                  ? wr_data : mem[rd_addr0];
      if (rd_en1)
        rd_data1 <= (wr_en && wr_addr == rd_addr1)
                  ? wr_data : mem[rd_addr1];
    end
  end
endmodule

Bypass này thay đổi cách chọn đầu vào nhưng không bỏ tầng thanh ghi đầu ra. Địa chỉ và yêu cầu được đưa trước cạnh; phản hồi được quan sát sau cạnh đó. Thanh ghi phía sau có thể nhận phản hồi tại cạnh lên tiếp theo. Đổi thành tập thanh ghi đọc tổ hợp sẽ thay đổi cả đường truyền từ thay đổi địa chỉ tới đầu ra và hợp đồng độ trễ; không thể coi đó chỉ là rút gọn mã.

Ví dụ: chỉ một cổng xung đột

Giả sử đã ghi M[2]=12 và M[5]=7. Ngay trước E0, bật cả hai enable đọc và đặt rd_addr0=2, rd_addr1=5, wr_en=1, wr_addr=2, wr_data=20. Sau E0, cổng 0 phản hồi giá trị bypass là 20, còn cổng 1 phản hồi giá trị lưu là 7. Cộng hai phản hồi hợp lệ này được 27, khác kết quả 19 của triển khai read-first không có bypass.

Ở E1, đặt cả hai địa chỉ đọc bằng 2 và ghi 30 vào đó. Cả hai đầu ra đều bằng 30. Ở E2, đọc địa chỉ 2 trong khi wr_en=0, wr_addr=2, wr_data=99; cả hai đầu ra phải bằng 30. Chỉ chu kỳ này đã có thể phát hiện lỗi bypass dựa riêng vào địa chỉ trùng nhau. Nếu rd_en0=0, rd_en1=1 ở E3, valid của cổng 0 bằng 0 và valid của cổng 1 bằng 1.

Mỗi cột ghi lại quan sát tại một cạnh lênCạnh lên Khoảnh khắc clock chuyển 0 sang 1, khác với mức cao chỉ cả khoảng CLK=1. Tìm hiểu thêm. Đầu vào là giá trị ngay trước cạnh, còn trạng thái có tên chứa after là giá trị ngay sau cập nhật. Cách căn cột thể hiện thứ tự lấy mẫu, không mô tả độ trễ lan truyềnĐộ trễ lan truyền Thời gian từ khi đầu vào đổi đến khi đầu ra ổn định ở giá trị đúng. Tương đương logic và đặc tính thời gian là hai vấn đề riêng. Tìm hiểu thêm vật lý. M[2]=12 và M[5]=7 đã được lưu trước; cả hai enable đọc luôn bằng 1. Địa chỉ ghi là 2. Ở cột cuối, wr_en=0 nên không được bypass wr_data=99.

Hai cổng chọn độc lập với cùng một phép ghi
Xem dữ liệu dạng sóng
Dữ liệu dạng sóng: mỗi ký tự là một khoảng; dấu chấm giữ trạng thái trước; p là một chu kỳ đồng hồ.
Tín hiệuDạng sóngGiá trị bus
edge234E0 → E1 → E2
wr_en1.0
wr_data23420 → 30 → 99
rd_addr02..2
rd_addr123.5 → 2
out0 after23.20 → 30
out1 after23.7 → 30

Cần khởi tạo những gì?

Reset đồng bộ tích cực mức cao chặn ghi và đưa hai valid về 0. Mảng và dữ liệu đầu ra không được reset. Vì vậy, bus đầu ra giữ giá trị trước đó sau reset vẫn là bình thường nếu valid=0. Nội dung đã lưu trong mảng không bị reset của RTL này xóa. Nếu hệ thống chỉ cho phép công việc mới sau reset, phải quy định riêng thứ tự khởi tạo cho công việc đó.

Khi đọc một địa chỉ tại cùng cạnh với lần ghi đầu, triển khai này có thể cho giá trị mới xác định nhờ bypass. Nhưng đọc địa chỉ chưa từng được khởi tạo mà không ghi vẫn cho giá trị chưa xác định. rd_valid đánh dấu thời điểm phản hồi yêu cầu, không phải bit initialized của từng địa chỉ. Trước khi tạo giá trị dự kiến cho đọc thông thường, bộ kiểm tra phải biết địa chỉ đó có giá trị đã biết hay chưa, và xử lý riêng trường hợp bypass ở cùng cạnh.

Các mục kiểm chứng gồm bốn tổ hợp enable của hai cổng đọc, địa chỉ giống/khác nhau, cổng xung đột với ghi là không cổng nào/cổng 0/cổng 1/cả hai, các lần ghi liên tiếp và ưu tiên reset. Nhiều cổng ghi nằm ngoài phạm vi bài này; nếu bổ sung, trước hết phải quy định lại ưu tiên khi hai phép ghi trùng địa chỉ. Thay đổi số cổng làm thay đổi đồng thời hợp đồng chức năng và chi phí tài nguyên.

Tự thử

Ban đầu M[1]=4, M[4]=9. Khi cả hai enable đọc bằng 1 và hai địa chỉ lần lượt là 1 và 4, nếu ghi 13 vào địa chỉ 4 thì cặp đầu ra là gì? Ở cạnh tiếp theo, nếu wr_en=0, wr_addr=1, wr_data=99 và cả hai địa chỉ đọc đều bằng 1 thì sao? Cuối cùng, giải thích valid và quy tắc tiêu thụ dữ liệu khi chỉ tắt enable cổng 0.

Đọc giải thích

Cặp phản hồi đầu tiên là (4,13). Chỉ cổng 1 trùng địa chỉ ghi nên bypass giá trị mới 13. Cặp tiếp theo là (4,4); wr_en=0 nên không dùng 99. Ở chu kỳ cuối, rd_valid0=0 và rd_valid1=1. Thanh ghi dữ liệu của cổng 0 giữ giá trị cũ nhưng không được tiêu thụ như phản hồi hợp lệ. Địa chỉ 0 có thể được ghi và đọc giống mọi địa chỉ khác.

Lựa chọn áp dụng cho trình duyệt này. Có thể đổi ở chân trang bất cứ lúc nào.