Related
I'm doing this question with Pascal (Google Kick Start 2020 Round A - Workout) and I ran into a problem that doesn't make any sense at all. Here is a part of my program:
var N,K,i,max,max1 : longint;
M : array [1..100000] of longint;
A : array [1..99999] of longint;
begin
readln(N,K);
for i := 1 to N do
read(M[i]);
for i := 1 to N-1 do A[i] := M[i+1]-M[i];
max := 0;
for i := 1 to N-1 do
if A[i] >= max then
begin
max := A[i];
max1 := i;
end;
writeln('max = ',max); writeln('max1 = ',max1);
readln; readln;
end.
So first I type in all the input data which are:
5 6 and
9
10
20
26
30.
When I run the program, the value of max is 10 and the value of max1 is 2.
But when I change the way max gets its value and totally did nothing with max1, the program becomes like this:
uses crt;
var N,K,i,max,max1 : longint;
M : array [1..100000] of longint;
A : array [1..99999] of longint;
begin
readln(N,K);
for i := 1 to N do
read(M[i]);
for i := 1 to N-1 do A[i] := M[i+1]-M[i];
max := 0;
for i := 1 to N-1 do
if A[i] >= max then
begin
max := i;
max1 := i;
end;
writeln('max = ',max); writeln('max1 = ',max1);
readln; readln;
end.
I run the program, and suddenly both the values of max and max1 are 4. How can this happen? Should I delete Pascal?? By the way if you can't install Pascal for some reasons then go to this link:https://www.onlinegdb.com/, select Pascal language and paste my program. Thanks for helping me!
My task is to implement a Processor with Data Memory using verilog. Instructions are hard coded (32 bit instructions). I have completed inserting a Data Memory.
For load and store instructions
But when complied i get- "warning: Port 8 (Destination) of instruction_reg expects 8 bits, got 1."
This a verilog code for a instruction set architecture
<pre><code>
//ALU created
module ALU(out,DATA1,DATA2,Select); //module for ALU
input [7:0]DATA1,DATA2;//8 bit data inputs
input [2:0] Select;//three bit selection
output [7:0]out;//8 bit data output
reg out;//outputt register
always#(DATA1,DATA2,Select)
begin
case(Select)
3'b000: out=DATA1;//forward
3'b001: out=DATA1+DATA2;//add
3'b010: out=DATA1 & DATA2;//and
3'b011: out=DATA1| DATA2; //or
endcase
end
endmodule
//here no need of its test bench
//registerFile created in part2
module Register(clk,busy_wait,INaddr,IN,OUT1addr,OUT1,OUT2addr,OUT2);
input clk;
input [2:0] INaddr;
input [7:0] IN;
input [2:0] OUT1addr;
output[7:0] OUT1;
input [2:0] OUT2addr;
output[7:0] OUT2;
input busy_wait; //new
reg [7:0] reg0, reg1, reg2, reg3,reg4,reg5,reg6,reg7;
assign OUT1 = OUT1addr == 0 ? reg0 :
OUT1addr == 1 ? reg1 :
OUT1addr == 2 ? reg2 :
OUT1addr == 3 ? reg3 :
OUT1addr == 4 ? reg4 :
OUT1addr == 5 ? reg5 :
OUT1addr == 6 ? reg6 :
OUT1addr == 7 ? reg7 : 0;
assign OUT2 = OUT2addr == 0 ? reg0 :
OUT2addr == 1 ? reg1 :
OUT2addr == 2 ? reg2 :
OUT2addr == 3 ? reg3 :
OUT2addr == 4 ? reg4 :
OUT2addr == 5 ? reg5 :
OUT2addr == 6? reg6 :
OUT2addr == 7 ? reg7 : 0;
always #(negedge clk)
begin
//check weather it is not busy
if (!busy_wait) begin
case(INaddr)
3'b000: reg0=IN;
3'b001: reg1=IN;
3'b010: reg2=IN;
3'b011: reg3=IN;
3'b100: reg4=IN;
3'b101: reg5=IN;
3'b110: reg6=IN;
3'b111: reg7=IN;
endcase
end
end
endmodule
//we need control unit
//we need twos compliment when substractor is called
module twos_compliment(IN,OUT); //twos complement
input [7:0] IN;
output signed [7:0] OUT;
assign OUT=-IN;
endmodule
//multiplexer is used to select value or compliment
module multiplex(IN1,IN2,OUT,SELECT); //multiplexer
input [7:0] IN1,IN2;
input SELECT;
output [7:0] OUT;
assign OUT = (SELECT) ? IN2 : IN1 ;
endmodule
//program counter is needed
module counter(clk,reset,busy_wait,addr); //module program counter
input clk,reset;
output [31:0] addr;
reg addr;
input busy_wait;
//in hardcoded instructions Memroy start is hexadecimal 00000000
always #(reset) begin
addr = 32'h00000000;
end
always #(negedge clk) begin
//now we have to check busy wait also
if(~reset && !busy_wait)
begin
addr = addr + 1;//addr is incremented by 1
end
else if (busy_wait) begin
addr <= addr ;
end
end
endmodule
//control unit
//input should be instruction opcode
//output should be select for alu and input to muxes
module CU(Instruction,busy_wait,opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,Destination,address); //control unit
input [7:0] opcode;
input [31:0] Instruction;
input [7:0] Destination;
//input [31:0] Instruction_code;//to extract load or Store Adress the Instruction code [23-16]
output [2:0] SELECT;
output mulx1,mulx2;
input busy_wait; //new
output memRead; //new
output memWrite;//new
output regWrite;//new
output [7:0] address;//new
reg mulx1,mulx2,memRead,memWrite,regWrite,address;
assign SELECT = opcode [2:0]; //select should be opcodes last three bits for alu
always #(opcode) begin
case(opcode)
8'b00000000:begin //for mov
mulx1 = 1'b1;
mulx2 = 1'b0;
end
8'b00000001:begin //for add
mulx1 = 1'b1;
mulx2 = 1'b0;
end
8'b00001001:begin //sub
mulx1 = 1'b1;
mulx2 = 1'b1;
end
8'b00000010:begin //and
mulx1 = 1'b1;
mulx2 = 1'b0;
end
8'b00000011:begin //or
mulx1 = 1'b1;
mulx2 = 1'b0;
end
8'b00001000:begin //for loadImmediate
mulx1 = 1'b0;
end
/*4'b0101:
begin
memRead = 1'b0;
memWrite = 1'b1;
address = instruction[23:16];
$display("oper = store");
end
// store to memory
*/
8'b00000101:begin //for store to Data memory(selected 00000101)
memRead = 1'b0;
memWrite = 1'b1;
assign address = Destination;
mulx1 = 1'b1;
mulx2 = 1'b1;
end
/*4'b0100:
// load from memory
begin
memWrite = 1'b0;
memRead = 1'b1;
address = instruction[7:0];
$display("oper = load");
end
*/
8'b00000100:begin //for load To register From Data memory (selected 00000100)
memWrite = 1'b0;
memRead = 1'b1;
assign address = Instruction[7:0];
mulx1 = 1'b1;
mulx2 = 1'b1;
end
default :
begin
memWrite = 1'b0;
memRead = 1'b0;
end
endcase
end
endmodule
//instruction memory 32 bits instead of memory
module instruction_mem(Read_addr,Instruction_code);
output [31:0] Instruction_code;
reg Instruction_code;
input [31:0] Read_addr;
always #(Read_addr) begin
case(Read_addr)
/*32'h00000000: Instruction_code = 32'b00001000 00000 100 00000000 11111111;// loadi 4 X 0xFF(255)
32'h00000001: Instruction_code = 32'b00001000 00000 110 00000000 10101010;// loadi 6 X 0xAA(170)
32'h00000002: Instruction_code = 32'b00001000 00000 011 00000000 10111011;// loadi 3 X 0xBB(187)
32'h00000003: Instruction_code = 32'b00000001 00000 101 00000 110 00000 011;// add 5 6 3
32'h00000004: Instruction_code = 32'b00000010 00000 001 00000 100 00000 101;// and 1 4 5
32'h00000005: Instruction_code = 32'b00000011 00000 010 00000 001 00000 110;// or 2 1 6
32'h00000006: Instruction_code = 32'b00000000 00000 111 00000 000 00000 010;// mov 7 x 2
32'h00000007: Instruction_code = 32'b00001001 00000 100 00000 111 00000 011;// sub 4 7 3
32'h00000008: Instruction_code = 32'b00000101 00000000 00000 000 00000 100; // store 0, X, 4
32'h00000009: Instruction_code = 32'b00000100 00000101 00000 000 00000 000; // load 5, X, 0*/
/*Hard coded instructions for Processor without memry is commented*/
/*32'h00000000: Instruction_code = 32'b00001000000001000000000011111111;// loadi 4 X 0xFF(255)
32'h00000001: Instruction_code = 32'b00001000000001100000000010101010;// loadi 6 X 0xAA(170)
32'h00000002: Instruction_code = 32'b00001000000000110000000010111011;// loadi 3 X 0xBB(187)
32'h00000003: Instruction_code = 32'b00000001000001010000011000000011;// add 5 6 3
32'h00000004: Instruction_code = 32'b00000010000000010000010000000101;// and 1 4 5
32'h00000005: Instruction_code = 32'b00000011000000100000000100000110;// or 2 1 6
32'h00000006: Instruction_code = 32'b00000000000001110000000000000010;// mov 7 x 2
32'h00000007: Instruction_code = 32'b00001001000001000000011100000011;// sub 4 7 3*/
//new instructions
32'h00000000: Instruction_code = 32'b00000101000000000000000000000100; // store 0, X, 4
32'h00000001: Instruction_code = 32'b00000100000001010000000000000000; // load 5, X, 0
endcase
end
endmodule
//inside the control unit a opcode should be divided in instruction reg
module instruction_reg(Instruction,clk,OPCODE,OUT1addr,OUT2addr,INaddr,Immediate,Destination);
input [31:0] Instruction;
input clk;
output[2:0] OUT1addr,OUT2addr,INaddr;
output [7:0] OPCODE,Immediate,Destination;
assign INaddr = Instruction[18:16];
assign OPCODE = Instruction[31:24];//31-24 taken declared as op code
assign Immediate = Instruction[7:0];//immediate value is 7-0
assign OUT1addr = Instruction[2:0]; //output1addr addredd of output data by the registerFile
assign OUT2addr = Instruction[10:8];
assign Destination=Instruction[23:16];//new
endmodule
//data memory
module data_mem(
clk,
rst,
read,
write,
address,
write_data,
read_data,
busy_wait
);
input clk;
input rst;
input read;
input write;
input[7:0] address;
input[7:0] write_data;
output[7:0] read_data;
output busy_wait;
reg[7:0] read_data;
reg busy_wait,clkMem=1'b0;
integer i;
// Declare memory 256x8 bits
reg [7:0] memory_array [255:0];
//reg [7:0] memory_ram_q [255:0];
always #(posedge rst)
begin
if (rst)
begin
for (i=0;i<256; i=i+1)
memory_array[i] <= 0;
end
end
always #1 clkMem = ~clkMem;
always #(posedge clkMem)
begin
if (write && !read && !busy_wait)
begin
busy_wait <= 1;
// artificially delay 100 cycles
repeat(10)
begin
#(posedge clk);
end
$display("writing to memory");
memory_array[address] = write_data;
busy_wait <= 0;
end
if (!write && read && !busy_wait)
begin
busy_wait <= 1;
// artificially delay 100 cycles
repeat(10)
begin
#(posedge clk);
end
$display("reading from memory");
read_data = memory_array[address];
busy_wait <= 0;
end
end
endmodule
//test bench
module for_processor_test();
wire [2:0] SELECT,OUT1addr,OUT2addr,INaddr;
wire mux1OUT,mux2OUT;
reg clk,reset,reset_reg;
wire [31:0] Read_addr,Instruction_code;
wire [7:0] OPCODE,Immediate,OUT1,OUT2,RESULT,twosComplement,mux2out,mux1out;
counter c1(clk,reset,busy_wait,Read_addr);
instruction_mem instruct_mem1(Read_addr,Instruction_code);
instruction_reg instruct_reg1(Instruction_code,clk,OPCODE,OUT1addr,OUT2addr,INaddr,Immediate,Destination);
CU cu1(Instruction_code,busy_wait,OPCODE,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,Destination,address);
//CU cu1(Instruction_code,busy_wait,opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,address);
//CU myCU(busy_wait,instruction, out_addr1, out_addr2, in_addr, select, data2_compli_control, immediate_control, immediate_value, memRead,memWrite,regWrite,address);
//(opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite)
Register regfile(clk,busy_wait,INaddr,RESULT,OUT1addr,OUT1,OUT2addr,OUT2);
twos_compliment tcmplmnt(OUT1,twosComplement);
multiplex mulx2(OUT1,twosComplement,mux2out,mux2OUT);
multiplex mulx1(Immediate,mux2out,mux1out,mux1OUT);
ALU alu(RESULT,mux1out,OUT2,SELECT);
data_mem mdata_mem(clk,rst,memRead,memWrite,address,write_data,read_data,busy_wait);
always #10 clk = ~clk;
initial begin
clk = 0;
reset = 1;
reset = 0;
reset_reg = 1;
reset_reg = 0;
#160
$finish;
end
initial begin
while(1) begin
#10 $display("INSTRUCTION=%b RESULT=%d clock=%d",Instruction_code,RESULT,clk);
//#20 $display("INSTRUCTION=%b RESULT=%d clock=%d",Instruction_code,RESULT,clk);
end
end
endmodule
</code></pre>
In module for_processor_test you have not declared Destination. Verilog is a pretty liberal language (by default), so it has implicitly declared a wire called Destination for you. However, this implicit wire will be only 1 bit wide. Hence, your error message.
If you want to tighten up this liberal behaviour (you do), then you can add this compile directive:
`default_nettype none
Had you done this, you would have got a more descriptive error message.
I want to create a circuit which has two inputs a clock and an enable
and three outputs. What I want this circuit to do is that it has a
variable (cont) that goes from "00" to "11" and two of the outputs
(sal_1 and sal_2) take the values of cont(0) and cont(1) and go to the
inputs of a ttl ic (AND , OR, XOR) and then the output of the ttl ic
goes back to the circuit and is saved (results) after that, the vector
that is created from the differents results of the ttl ic ouputs is
compared with vectors already predefined and find the one that matches
it and returns the value.
I have a hard time with the output and then input times, it seems that
there is a special way to do this.
Here is my code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
entity ttl_finder is
port( clk, ena, sal_ttl : in std_logic;
sal_1, sal_2 : out std_logic;
sal_f : out std_logic_vector(3 downto 0));
end entity;
architecture ttl_tester of ttl_finder is
signal cont : std_logic_vector(1 downto 0) := "00";
signal results : std_logic_vector(3 downto 0) := "0000";
begin
process(clk, ena)
variable c : std_logic;
variable d : std_logic;
variable e : std_logic;
begin
if ena = '1' then
if cont < "11" then
sal_1 <= cont(0);
sal_2 <= cont(1);
if rising_edge(clk) then
results(conv_integer(cont)) <= sal_ttl;
end if;
cont <= cont + 1;
else
sal_1 <= cont(0);
sal_2 <= cont(1);
if rising_edge(clk) then
results(conv_integer(cont)) <= sal_ttl;
end if;
cont <= "00";
end if;
end if;
end process;
sal_f <= results;
end ttl_tester;
How to check if a binary number can be divided by 10 (decimal), without converting it to other system.
For example, we have a number:
1010 1011 0100 0001 0000 0100
How we can check that this number is divisible by 10?
First split the number into odd and even bits (I'm calling "even" the
bits corresponding to even powers of 2):
100100110010110000000101101110
0 1 0 1 0 0 1 0 0 0 1 1 0 1 0 even 1 0 0 1 0 1 1 0 0 0 0 0 1 1 1 odd
Now in each of these, add and subtract the digits alternately, as in
the standard test for divisibility by 11 in decimal (starting with
addition at the right):
100100110010110000000101101110 +0-1+0-1+0-0+1-0+0-0+1-1+0-1+0 =
-2 +1-0+0-1+0-1+1-0+0-0+0-0+1-1+1 = 1
Now double the sum of the odd digits and add it to the sum of the even
digits:
2*1 + -2 = 0
If the result is divisible by 5, as in this case, the number itself is
divisible by 5.
Since this number is also divisible by 2 (the rightmost digit being
0), it is divisible by 10.
Link
If you are talking about computational methods, you can do a divisiblity-by-5 test and a divisibility-by-2 test.
The numbers below assume unsigned 32-bit arithmetic, but can easily be extended to larger numbers.
I'll provide some code first, followed by a more textual explanation:
unsigned int div5exact(unsigned int n)
{
// returns n/5 as long as n actually divides 5
// (because 'n * (INV5 * 5)' == 'n * 1' mod 2^32
#define INV5 0xcccccccd
return n * INV5;
}
unsigned int divides5(unsigned int n)
{
unsigned int q = div5exact(n);
if (q <= 0x33333333) /* q*5 < 2^32? */
{
/* q*5 doesn't overflow, so n == q*5 */
return 1;
}
else
{
/* q*5 overflows, so n != q*5 */
return 0;
}
}
int divides2(unsigned int n)
{
/* easy divisibility by 2 test */
return (n & 1) == 0;
}
int divides10(unsigned int n)
{
return divides2(n) && divides5(n);
}
/* fast one-liner: */
#define DIVIDES10(n) ( ((n) & 1) == 0 && ((n) * 0xcccccccd) <= 0x33333333 )
Divisibility by 2 is easy: (n&1) == 0 means that n is even.
Divisibility by 5 involves multiplying by the inverse of 5, which is 0xcccccccd (because 0xcccccccd * 5 == 0x400000001, which is just 0x1 if you truncate to 32 bits).
When you multiply n*5 by the inverse of 5, you get n * 5*(inverse of 5), which in 32-bit math simplifies to n*1 .
Now let's say n and q are 32-bit numbers, and q = n*(inverse of 5) mod 232.
Because n is no greater than 0xffffffff, we know that n/5 is no greater than (232-1)/5 (which is 0x33333333). Therefore, we know if q is less than or equal to (232-1)/5, then we know n divides exactly by 5, because q * 5 doesn't get truncated in 32 bits, and is therefore equal to n, so n divides q and 5.
If q is greater than (232-1)/5, then we know it doesn't divide 5, because there is a one-one mapping between the 32-bit numbers divisible by 5 and the numbers between 0 and (232-1)/5, and so any number out of this range doesn't map to a number that's divisible by 5.
Here is the code in python to check the divisibilty by 10 using bitwise technique
#taking input in string which is a binary number eg: 1010,1110
s = input()
#taking initial value of x as o
x = 0
for i in s:
if i == '1':
x = (x*2 + 1) % 10
else:
x = x*2 % 10
#if x is turn to be 0 then it is divisible by 10
if x:
print("Not divisible by 10")
else:
print("Divisible by 10")
How can I represent integer as Binary?
so I can print 7 as 111
You write a function to do this.
num=7
function toBits(num)
-- returns a table of bits, least significant first.
local t={} -- will contain the bits
while num>0 do
rest=math.fmod(num,2)
t[#t+1]=rest
num=(num-rest)/2
end
return t
end
bits=toBits(num)
print(table.concat(bits))
In Lua 5.2 you've already have bitwise functions which can help you ( bit32 )
Here is the most-significant-first version, with optional leading 0 padding to a specified number of bits:
function toBits(num,bits)
-- returns a table of bits, most significant first.
bits = bits or math.max(1, select(2, math.frexp(num)))
local t = {} -- will contain the bits
for b = bits, 1, -1 do
t[b] = math.fmod(num, 2)
num = math.floor((num - t[b]) / 2)
end
return t
end
There's a faster way to do this that takes advantage of string.format, which converts numbers to base 8. It's trivial to then convert base 8 to binary.
--create lookup table for octal to binary
oct2bin = {
['0'] = '000',
['1'] = '001',
['2'] = '010',
['3'] = '011',
['4'] = '100',
['5'] = '101',
['6'] = '110',
['7'] = '111'
}
function getOct2bin(a) return oct2bin[a] end
function convertBin(n)
local s = string.format('%o', n)
s = s:gsub('.', getOct2bin)
return s
end
If you want to keep them all the same size, then do
s = string.format('%.22o', n)
Which gets you 66 bits. That's two extra bits at the end, since octal works in groups of 3 bits, and 64 isn't divisible by 3. If you want 33 bits, change it to 11.
If you have the BitOp library, which is available by default in LuaJIT, then you can do this:
function convertBin(n)
local t = {}
for i = 1, 32 do
n = bit.rol(n, 1)
table.insert(t, bit.band(n, 1))
end
return table.concat(t)
end
But note this only does the first 32 bits! If your number is larger than 2^32, the result wont' be correct.
function bits(num)
local t={}
while num>0 do
rest=num%2
table.insert(t,1,rest)
num=(num-rest)/2
end return table.concat(t)
end
Since nobody wants to use table.insert while it's useful here
Here is a function inspired by the accepted answer with a correct syntax which returns a table of bits in wriiten from right to left.
num=255
bits=8
function toBits(num, bits)
-- returns a table of bits
local t={} -- will contain the bits
for b=bits,1,-1 do
rest=math.fmod(num,2)
t[b]=rest
num=(num-rest)/2
end
if num==0 then return t else return {'Not enough bits to represent this number'}end
end
bits=toBits(num, bits)
print(table.concat(bits))
>>11111111
function reverse(t)
local nt = {} -- new table
local size = #t + 1
for k,v in ipairs(t) do
nt[size - k] = v
end
return nt
end
function tobits(num)
local t={}
while num>0 do
rest=num%2
t[#t+1]=rest
num=(num-rest)/2
end
t = reverse(t)
return table.concat(t)
end
print(tobits(7))
# 111
print(tobits(33))
# 100001
print(tobits(20))
# 10100
local function tobinary( number )
local str = ""
if number == 0 then
return 0
elseif number < 0 then
number = - number
str = "-"
end
local power = 0
while true do
if 2^power > number then break end
power = power + 1
end
local dot = true
while true do
power = power - 1
if dot and power < 0 then
str = str .. "."
dot = false
end
if 2^power <= number then
number = number - 2^power
str = str .. "1"
else
str = str .. "0"
end
if number == 0 and power < 1 then break end
end
return str
end
May seem more verbose but it is actually faster than other functions that use the math library functions. Works with any number, be it positive/negative/fractional...
local function tobits(num, str) -- tail call
str = str or "B"
if num == 0 then return str end
return tobits(
num >> 1 , -- right shift
((num & 1)==1 and "1" or "0") .. str )
end
This function uses a lookup table to print a binary number extracted from a hex representation. All using string manipulation essentially. Tested in lua 5.1.
local bin_lookup = {
["0"] = "0000",
["1"] = "0001",
["2"] = "0010",
["3"] = "0011",
["4"] = "0100",
["5"] = "0101",
["6"] = "0110",
["7"] = "0111",
["8"] = "1000",
["9"] = "1001",
["A"] = "1010",
["B"] = "1011",
["C"] = "1100",
["D"] = "1101",
["E"] = "1110",
["F"] = "1111"
}
local print_binary = function(value)
local hs = string.format("%.2X", value) -- convert number to HEX
local ln, str = hs:len(), "" -- get length of string
for i = 1, ln do -- loop through each hex character
local index = hs:sub(i, i) -- each character in order
str = str .. bin_lookup[index] -- lookup a table
str = str .. " " -- add a space
end
return str
end
print(print_binary(45))
#0010 1101
print(print_binary(65000))
#1111 1101 1110 1000
This maybe not work in lua that has no bit32 library
function toBinary(number, bits)
local bin = {}
bits = bits - 1
while bits >= 0 do --As bit32.extract(1, 0) will return number 1 and bit32.extract(1, 1) will return number 0
--I do this in reverse order because binary should like that
table.insert(bin, bit32.extract(number, bits))
bits = bits - 1
end
return bin
end
--Expected result 00000011
print(table.concat(toBinary(3, 8)))
This need at least lua 5.2 (because the code need bit32 library)
As by Dave, but with filled empty bits:
local function toBits(num, bits)
-- returns a table of bits, least significant first.
local t={} -- will contain the bits
bits = bits or 8
while num>0 do
rest=math.fmod(num,2)
t[#t+1]=rest
num=math.floor((num-rest)/2)
end
for i = #t+1, bits do -- fill empty bits with 0
t[i] = 0
end
return t
end
for i = 0, 255 do
local bits = toBits(i)
print(table.concat(bits, ' '))
end
Result:
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
1 0 1 0 0 0 0 0
...
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1