2009-02-23 34 views
16

Mặc dù tôi đã gắn thẻ bài tập về nhà này, nó thực sự là một khóa học mà tôi tự làm một cách miễn phí. Dù sao, khóa học này được gọi là "Từ Nand đến Tetris" và tôi hy vọng một người nào đó ở đây đã xem hoặc tham gia khóa học để tôi có thể nhận được một số trợ giúp. Tôi đang ở giai đoạn mà tôi đang xây dựng ALU với ngôn ngữ hdl được cung cấp. Vấn đề của tôi là tôi không thể lấy chip để biên dịch đúng cách. Tôi gặp lỗi khi cố gắng đặt cờ đầu ra cho ALU. Tôi tin rằng vấn đề là tôi không thể subscript bất kỳ biến trung gian, kể từ khi tôi chỉ cố gắng thiết lập các cờ để đúng hay sai dựa trên một số biến ngẫu nhiên (nói một lá cờ đầu vào), tôi không nhận được các lỗi. Tôi biết vấn đề không phải là với các chip tôi đang cố gắng sử dụng kể từ khi tôi đang sử dụng tất cả các chip được xây dựng.Làm cách nào để đặt cờ đầu ra cho ALU trong khóa học "Nand ​​to Tetris"?

Đây là con chip ALU của tôi cho đến nay:

/** 
* The ALU. Computes a pre-defined set of functions out = f(x,y) 
* where x and y are two 16-bit inputs. The function f is selected 
* by a set of 6 control bits denoted zx, nx, zy, ny, f, no. 
* The ALU operation can be described using the following pseudocode: 
*  if zx=1 set x = 0  // 16-bit zero constant 
*  if nx=1 set x = !x  // Bit-wise negation 
*  if zy=1 set y = 0  // 16-bit zero constant 
*  if ny=1 set y = !y  // Bit-wise negation 
*  if f=1 set out = x + y // Integer 2's complement addition 
*  else set out = x & y // Bit-wise And 
*  if no=1 set out = !out // Bit-wise negation 
* 
* In addition to computing out, the ALU computes two 1-bit outputs: 
*  if out=0 set zr = 1 else zr = 0 // 16-bit equality comparison 
*  if out<0 set ng = 1 else ng = 0 // 2's complement comparison 
*/ 

CHIP ALU { 

IN // 16-bit inputs: 
    x[16], y[16], 
    // Control bits: 
    zx, // Zero the x input 
    nx, // Negate the x input 
    zy, // Zero the y input 
    ny, // Negate the y input 
    f, // Function code: 1 for add, 0 for and 
    no; // Negate the out output 

OUT // 16-bit output 
    out[16], 

    // ALU output flags 
    zr, // 1 if out=0, 0 otherwise 
    ng; // 1 if out<0, 0 otherwise 

PARTS: 
// Zero the x input 
Mux16(a=x, b=false, sel=zx, out=x2); 

// Zero the y input 
Mux16(a=y, b=false, sel=zy, out=y2); 

// Negate the x input 
Not16(in=x, out=notx); 
Mux16(a=x, b=notx, sel=nx, out=x3); 

// Negate the y input 
Not16(in=y, out=noty); 
Mux16(a=y, b=noty, sel=ny, out=y3); 

// Perform f 
Add16(a=x3, b=y3, out=addout); 
And16(a=x3, b=y3, out=andout); 
Mux16(a=andout, b=addout, sel=f, out=preout); 

// Negate the output 
Not16(in=preout, out=notpreout); 
Mux16(a=preout, b=notpreout, sel=no, out=out); 

// zr flag 
Or8way(in=out[0..7], out=zr1); // PROBLEM SHOWS UP HERE 
Or8way(in=out[8..15], out=zr2); 
Or(a=zr1, b=zr2, out=zr); 

// ng flag 
Not(in=out[15], out=ng); 

} 

Vì vậy, vấn đề xuất hiện khi tôi đang cố gắng để gửi một phiên bản subscripted của 'ra khỏi' để chip Or8Way. Tôi đã thử sử dụng một biến khác với 'out', nhưng với cùng một vấn đề. Sau đó, tôi đọc rằng bạn không thể subscript biến trung gian. Tôi nghĩ có lẽ nếu tôi gửi biến trung gian cho một số con chip khác, và con chip đó đã ghi lại nó, nó sẽ giải quyết vấn đề, nhưng nó có cùng lỗi. Thật không may tôi chỉ không thể nghĩ ra một cách để thiết lập các cờ zr và ng mà không có subscripting một số biến trung gian, vì vậy tôi thực sự bị mắc kẹt!

Chỉ cần để bạn biết, nếu tôi thay thế các dòng có vấn đề với những điều sau đây, nó sẽ biên dịch (nhưng không cho kết quả đúng vì tôi chỉ sử dụng một số đầu vào ngẫu nhiên):

// zr flag 
Not(in=zx, out=zr); 

// ng flag 
Not(in=zx, out=ng); 

Bất cứ ai có bất cứ ý tưởng?

Chỉnh sửa: Đây là số appendix of the book for the course chỉ định cách thức hoạt động của hdl. Cụ thể nhìn vào phần 5 mà nói về xe buýt và nói: "Một pin nội bộ (như v ở trên) có thể không được subscripted".

Chỉnh sửa: Đây là lỗi chính xác tôi nhận được: "Dòng 68, Không thể kết nối đầu ra của cổng với một phần". Các thông báo lỗi là loại khó hiểu mặc dù, vì đó dường như không phải là vấn đề thực tế. Nếu tôi chỉ thay thế "Or8way (in = out [0..7], out = zr1);" với "Or8way (in = false, out = zr1);" nó sẽ không tạo ra lỗi này, đó là những gì dẫn tôi tìm kiếm trong phụ lục và thấy rằng biến ngoài, vì nó được bắt nguồn như là trung gian, không thể được subscripted.

+1

Tại sao câu hỏi này bị đóng? Nó chắc chắn đã giúp rất nhiều du khách được chứng minh bằng những upvotes và câu trả lời. –

+0

Bỏ phiếu để mở lại, bởi vì câu hỏi là về một vấn đề phổ biến khi giải quyết một vấn đề trong một khóa học trực tuyến nổi tiếng. –

Trả lời

5

Các giải pháp như Pax đề nghị là sử dụng một biến trung gian như là đầu vào để một chip khác, chẳng hạn như Or16Way. Đây là đoạn mã sau khi tôi cố định vấn đề và sửa lỗi:

CHIP ALU { 

IN // 16-bit inputs: 
    x[16], y[16], 
    // Control bits: 
    zx, // Zero the x input 
    nx, // Negate the x input 
    zy, // Zero the y input 
    ny, // Negate the y input 
    f, // Function code: 1 for add, 0 for and 
    no; // Negate the out output 

OUT // 16-bit output 
    out[16], 

    // ALU output flags 
    zr, // 1 if out=0, 0 otherwise 
    ng; // 1 if out<0, 0 otherwise 

PARTS: 
// Zero the x input 
Mux16(a=x, b=false, sel=zx, out=x2); 

// Zero the y input 
Mux16(a=y, b=false, sel=zy, out=y2); 

// Negate the x input 
Not16(in=x2, out=notx); 
Mux16(a=x2, b=notx, sel=nx, out=x3); 

// Negate the y input 
Not16(in=y2, out=noty); 
Mux16(a=y2, b=noty, sel=ny, out=y3); 

// Perform f 
Add16(a=x3, b=y3, out=addout); 
And16(a=x3, b=y3, out=andout); 
Mux16(a=andout, b=addout, sel=f, out=preout); 

// Negate the output 
Not16(in=preout, out=notpreout); 
Mux16(a=preout, b=notpreout, sel=no, out=preout2); 

// zr flag 
Or16Way(in=preout2, out=notzr); 
Not(in=notzr, out=zr); 

// ng flag 
And16(a=preout2, b=true, out[15]=ng); 

// Get final output 
And16(a=preout2, b=preout2, out=out); 
} 
+0

Kỳ lạ là không có thiết bị đệm và bạn phải hoàn nguyên và16/16 với các đầu vào giống nhau để mô phỏng điều này. Thiết bị điện tử thực có bộ đệm mà không lãng phí cổng, có lẽ chương trình mô phỏng này cũng phải có. – paxdiablo

+0

Có, phải có một số giải pháp khác không yêu cầu tôi tạo chip mới (tôi đã thực hiện Or16Way), vì ý tưởng là chỉ sử dụng các chip mà bạn xây dựng trong các dự án trước đó. – MahlerFive

+4

bạn không phải tạo chip mới. Chỉ cần sử dụng nhiều đầu ra, như sau: Mux16 (a = F16, b = NF16, sel = không, out = out, out [15] = ng, out [0..7] = zout1, out [8 ..15] = zout2); Sau đó sử dụng Or16Way trên các đầu ra đó: \t Or8Way (in = zout1, out = zr1); \t Or8Way (in = zout2, out = zr2); \t Hoặc (a = zr1, b = zr2, out = zr3); \t Không (in = zr3, out = zr); – mudge

1

Các bạn đã thử:

// zr flag 
Or8way(
    in[0]=out[ 0], in[1]=out[ 1], in[2]=out[ 2], in[3]=out[ 3], 
    in[4]=out[ 4], in[5]=out[ 5], in[6]=out[ 6], in[7]=out[ 7], 
    out=zr1); 
Or8way(
    in[0]=out[ 8], in[1]=out[ 9], in[2]=out[10], in[3]=out[11], 
    in[4]=out[12], in[5]=out[13], in[6]=out[14], in[7]=out[15], 
    out=zr2); 
Or(a=zr1, b=zr2, out=zr); 

Tôi không biết nếu điều này sẽ làm việc nhưng nó dường như có ý nghĩa từ nhìn vào tài liệu này here.

Tôi cũng nên cân nhắc việc sử dụng out làm tên biến vì khó hiểu khi tìm ra sự khác biệt giữa từ khóa đó và từ khóa out (như trong "out=..."). Sau khi chỉnh sửa, nếu bạn không thể đăng ký các giá trị trung gian, thì có vẻ như bạn sẽ phải triển khai một "con chip" riêng lẻ như IsZero16, giá trị 16 bit là đầu vào (số out trung gian) cho biết số 0 của nó mà bạn có thể tải vào zr. Hoặc bạn có thể tạo ra một con chip IsZero8 nhưng bạn phải gọi nó là hai giai đoạn như bạn hiện đang làm với Or8Way.

Điều này có vẻ như một giải pháp hợp lệ vì bạn có thể chỉ số giá trị đầu vào cho chip.

Và, chỉ cần nhìn vào lỗi, đây có thể là vấn đề khác với vấn đề bạn đề xuất. Cụm từ "Không thể kết nối chốt đầu ra của cổng với một phần" có nghĩa là tôi không thể kết nối các tín hiệu từ tham số đầu ra trở lại vào vùng xử lý chip. Điều đó có ý nghĩa từ quan điểm điện.

Bạn có thể thấy bạn phải lưu đầu ra thành biến tạm thời và sử dụng cả hai thiết lập zrout (vì một khi tín hiệu đã được "gửi" tới chân đầu ra của chip, chúng có thể không còn khả dụng nữa).

Chúng ta có thể thử:

CHIP SetFlags16 { 
    IN inpval[16]; 
    OUT zflag,nflag; 
    PARTS: 
     Or8way(in=inpval[0.. 7],out=zr0); 
     Or8way(in=inpval[8..15],out=zr1); 
     Or(a=zr0,b=zr1,out=zflag); 
     Not(in=inpval[15],out=nflag); 
} 

và sau đó, trong con chip ALU của bạn, sử dụng này ở cuối:

// Negate the output 
Not16(in=preout, out=notpreout); 
Mux16(a=preout, b=notpreout, sel=no, out=tempout); 

// flags 
SetFlags16(inpval=tempout,zflag=zr,nflag=ng); 

// Transfer tempout to out (may be a better way). 
Or16(a=tempout,b=tempout,out=out); 
+0

Vấn đề là tôi không thể subscript biến 'ra' ở tất cả vì nó đã được bắt nguồn như là một biến trung gian. Ngoài ra, cho dù bạn chỉ định từng chỉ số riêng lẻ hay không thì cũng không quan trọng. Nếu 'in' có kích thước bus là 8, thì bên phải của phương trình phải có kích thước 8. – MahlerFive

+0

Cho chúng tôi thấy lỗi thực tế bạn đang gặp phải, @MahlerFive. Nó có thể hỗ trợ. – paxdiablo

+0

Được rồi, tôi đã đăng rằng dưới dạng bản chỉnh sửa – MahlerFive

21

Đối với bất cứ ai khác quan tâm, giải pháp giả lập hỗ trợ là sử dụng nhiều đầu ra Cái gì như:

Mux16(a=preout, b=notpreout, sel=no, out=out,out=preout2,out[15]=ng); 
1

Dưới đây là một còn với một chip mới nhưng nó cảm thấy sạch hơn

/** 
* Negator16 - negates the input 16-bit value if the selection flag is lit 
*/ 
CHIP Negator16 { 
    IN sel,in[16]; 
    OUT out[16]; 

    PARTS: 
    Not16(in=in, out=negateIn); 
    Mux16(a=in, b=negateIn, sel=sel, out=out); 
} 

CHIP ALU { 
    // IN and OUT go here... 
    PARTS: 
    //Zero x and y if needed 
    Mux16(a=x, b[0..15]=false, sel=zx, out=x1); 
    Mux16(a=y, b[0..15]=false, sel=zy, out=y1); 

    //Create x1 and y1 negations if needed 
    Negator16(in=x1, sel=nx, out=x2); 
    Negator16(in=y1, sel=ny, out=y2); 

    //Create x&y and x+y 
    And16(a=x2, b=y2, out=andXY); 
    Add16(a=x2, b=y2, out=addXY); 

    //Choose between And/Add according to selection 
    Mux16(a=andXY, b=addXY, sel=f, out=res); 

    // negate if needed and also set negative flag 
    Negator16(in=res, sel=no, out=res1, out=out, out[15]=ng); 

    // set zero flag (or all bits and negate) 
    Or16Way(in=res1, out=nzr); 
    Not(in=nzr, out=zr); 
} 
5

Đây là cách tôi đã làm ALU:

CHIP ALU { 
IN // 16-bit inputs: 
    x[16], y[16], 
    // Control bits: 
    zx, // Zero the x input 
    nx, // Negate the x input 
    zy, // Zero the y input 
    ny, // Negate the y input 
    f, // Function code: 1 for add, 0 for and 
    no; // Negate the out output 
OUT // 16-bit output 
    out[16], 
    // ALU output flags 
    zr, // 1 if out=0, 0 otherwise 
    ng; // 1 if out<0, 0 otherwise 
PARTS:  
    Mux16(a=x, b=false, sel=zx, out=M16x); 
    Not16(in=M16x, out=Nx); 
    Mux16(a=M16x, b=Nx, sel=nx, out=M16M16x); 

    Mux16(a=y, b=false, sel=zy, out=M16y); 
    Not16(in=M16y, out=Ny); 
    Mux16(a=M16y, b=Ny, sel=ny, out=M16M16y); 

    And16(a=M16M16x, b=M16M16y, out=And16); 
    Add16(a=M16M16x, b=M16M16y, out=Add16); 
    Mux16(a=And16, b=Add16, sel=f, out=F16); 

    Not16(in=F16, out=NF16); 
    Mux16(a=F16, b=NF16, sel=no, out=out, out[15]=ng, out[0..7]=zout1, out[8..15]=zout2); 

    Or8Way(in=zout1, out=zr1); 
    Or8Way(in=zout2, out=zr2); 
    Or(a=zr1, b=zr2, out=zr3); 
    Not(in=zr3, out=zr); 
} 
Các vấn đề liên quan