Giới thiệu chủ đề
Liên kết câu hỏi
Cuộc sống ở Conway.
Giới thiệu
Câu hỏi yêu cầu chúng ta triển khai một mạch cho Trò chơi cuộc sống của Conway.
Trò chơi được chơi trong một không gian lưới hai chiều, trong câu hỏi này có kích thước 16 * 16. Mỗi lưới có hai trạng thái (0 hoặc 1), đại diện cho chết hoặc sống.
luật lệ:
- Ở cạnh tăng của đồng hồ, lưới cần được cập nhật.
- tín hiệu trẻ trọng tải ở mức cao, nó được cập nhật vào dữ liệu đầu vào dữ liệu 。
- Nếu không, việc cập nhật trạng thái của mỗi lưới có liên quan đến trạng thái của các lưới ở tám hướng xung quanh nó.
- Nếu lưới ở tám hướng xung quanh nó có 2 Nếu một người còn sống, trạng thái vẫn còn.
- Nếu lưới theo mọi hướng xung quanh nó có 3 còn sống thì trạng thái của lưới được cập nhật thành 1 (sống).
- Ngược lại, trạng thái lưới sẽ được cập nhật thành 0 (chết).
- Lưới có hai chiều, nhưng lưới được lưu trữ được lưu trữ ở một chiều. q[15 : 0] là hàng 0, q[31 : 16] là hàng 1 。
- Lưới 16 * 16 hai chiều không có viền, một bên kéo dài sang cặp cạnh kia.
Phân tích câu hỏi
Giải pháp 1
Vì là mạng mở rộng nên chúng ta có thể trực tiếp mở rộng mạng 16 * 16 thành mạng 18 * 18. Theo cách này, lưới 16 * 16 ở giữa là thứ chúng tôi muốn cập nhật và vòng tròn bên ngoài là mạng mở rộng hình khuyên.
Sau đó, bạn có thể trực tiếp sử dụng vòng lặp để tránh các tình huống vượt quá giới hạn và cập nhật trực tiếp.
Giải pháp 2
Đối với một lưới nhất định, hãy liệt kê kỹ lưỡng tình hình lưới theo từng hướng, sau đó tính toán số lượng lưới còn sót lại xung quanh nó, sau đó cập nhật. Lặp lại 256 lần để cập nhật tất cả các lưới.
Vì vậy, bây giờ, hãy xác định 8 hướng này, đó là (lên, xuống, trái, phải, up_left, up_right, down_left, down_right).
Biến viết tắt là:
dây [255:0] q_u; dây [255:0] q_l; dây [255:0] q_r; dây [255:0] q_d; dây [255:0] q_ul; dây [255:0] q_ur; dây [255:0] q_dl; dây [255:0] q_dr;
Đầu tiên, chúng ta hãy xem cách tính bốn hướng lên, xuống, trái và phải.
hướng dọc
Lưới ban đầu được xác định là, đầu ra [255 : 0] q . Sau đó cho ô lưới được đánh số i. Số lưới phía trên của nó rõ ràng là i-16.
Nhưng nếu đơn vị i ở hàng 0 thì i - 16 sẽ là số âm. Trên thực tế, nó phải ở hàng 15.
Vì vậy, chỉ cần sử dụng thao tác ghép vector của Verilog.
gán q_u = {q[239:0], q[255:240]},
Lý do tương tự.
gán q_d = {q[15:0], q[255:16]},
hướng trái và phải
Đối với ô lưới i, phía bên trái là i - 1. Nhưng khi ô ở cột 0 thì bên trái của ô đó phải là cột 15 của cùng hàng. Điều tương tự cũng xảy ra với phía bên phải.
đối với (i = 0; i < 16; i ++ ) bắt đầu: t1 gán q_l[i * 16 + 15 : i * 16] = {q[i * 16 + 15 - 1 : i * 16], q[i * 16 + 15]}; gán q_r[i * 16 + 15 : i * 16] = {q[i * 16], q[i * 16 + 15 : i * 16 + 1]}; kết thúc
hướng chéo
Khi xử lý các đường chéo, không thể nói lên, xuống, trái và phải như nhau.
Bạn sẽ thấy có nhiều trường hợp đặc biệt (xuyên biên) (một hàng và một cột) nên lúc này hãy sử dụng trực tiếp các chiều lên xuống đã tính toán trước đó, kết hợp với quá trình tính toán các chiều trái phải, để lấy hướng chéo.
Phía trên bên trái của ô lưới có phải là phía trên bên trái không?
Triển khai mã
Mã này bao gồm một khối tạo for.
mô-đun top_module(đầu vào clk, tải đầu vào, đầu vào [255:0] dữ liệu, đầu ra [255:0] q); dây [255:0] q_u; dây [255:0] q_l; dây [255:0] q_r; dây [255:0] q_d; dây [255:0] q_ul; dây [255:0] q_ur; dây [255:0] q_dl; dây [255:0] q_dr; số nguyên j; reg [3:0] cnt; gán q_u = {q[239:0], q[255:240]}; gán q_d = {q[15:0], q[255:16]}; genvar i; tạo cho (i = 0; i < 16; i ++) bắt đầu: t1 gán q_l[i * 16 + 15 : i * 16] = {q[i * 16 + 15 - 1 : i * 16], q[i * 16 + 15]}; gán q_r[i * 16 + 15 : i * 16] = {q[i * 16], q[i * 16 + 15 : i * 16 + 1]}; gán q_ul[i * 16 + 15 : i * 16] = {q_u[i * 16 + 15 - 1 : i * 16], q_u[i * 16 + 15]}; gán q_ur[i * 16 + 15 : i * 16] = {q_u[i * 16], q_u[i * 16 + 15 : i * 16 + 1]}; gán q_dl[i * 16 + 15 : i * 16] = {q_d[i * 16 + 15 - 1 : i * 16], q_d[i * 16 + 15]}; gán q_dr[i * 16 + 15 : i * 16] = {q_d[i * 16], q_d[i * 16 + 15 : i * 16 + 1]}; kết thúc endgenerate luôn @(posedge clk) bắt đầu nếu (tải) bắt đầu q <= dữ liệu; kết thúc nếu không thì bắt đầu cho (j = 0; j < 256; j = j + 1) bắt đầu cnt = q_u[j] + q_d[j] + q_l[j] + q_r[j] + q_ul[j] + q_ur[j] + q_dl[j] + q_dr[j]; trường hợp (cnt) 4'd2: q[j] <= q[j]; 4'd3: q[j] <= 1; mặc định: q[j] <= 0; kết thúc trường hợp kết thúc kết thúc kết thúc mô-đun
tạo ra cho
cái
Chức năng chính của generate for là sao chép các mô-đun hoặc thành phần, luôn chặn và gán các câu lệnh.
Khi sử dụng generate for, bạn phải chú ý đến các yêu cầu sau.
- đang được sử dụng
tạo ra cho
đầu tiên phải khai báo một Genève biến, được sử dụng như vì biến vòng lặp. Genève
là một loại biến trong câu lệnh tạo, được sử dụng trong tạo ra cho
Câu lệnh khai báo một biến chỉ số nguyên dương.
-
vì
Các câu lệnh nhúng bên trong phải được viết bằng bắt đầu-kết thúc
bên trong
- Hãy cố gắng để đúng
bắt đầu-kết thúc
Đặt tên khối trình tự
Ví dụ cú pháp của generate for như sau:
genvar i; tạo cho (i = 0; i < 4; i = i + 1) bắt đầu: gen_assign_temp gán temp[i] = indata[2 * i + 1 : 2 * i]; kết thúc endgenerate
Cuối cùng, bài viết về HDLbits_Conwaylife này kết thúc tại đây. Nếu bạn muốn biết thêm về HDLbits_Conwaylife, vui lòng tìm kiếm các bài viết về CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!