Created
June 13, 2012 12:09
-
-
Save geoffrasb/2923674 to your computer and use it in GitHub Desktop.
brainfuck implementation in verilog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Console_module ( | |
input reset, | |
output [7:0] LCD_DATA, | |
output LCD_ENABLE, | |
output LCD_RW, | |
output LCD_RSTN, | |
output LCD_CS1, | |
output LCD_CS2, | |
output LCD_DI, | |
input lcd_clock, | |
input working_clock, | |
//abstract interface | |
input to_mode, | |
input change_mode, | |
input please_wait, | |
//input [13:0]mem_monitor1, | |
input [13:0]mem_monitor2, | |
//input [13:0]mem_monitor3, | |
input [3:0]symbol_to_insert, | |
input insert, | |
input delete, | |
input cursor_dir, | |
input move_cursor | |
); | |
parameter ceo = 4'b1001, | |
reg output_device = 0; | |
reg output_device_next = 0; | |
LCD_display_module lcd( | |
.lcd_clock(lcd_clock), | |
.working_clock(working_clock), | |
.LCD_DATA(LCD_DATA), | |
.LCD_ENABLE(LCD_ENABLE), | |
.LCD_RW(LCD_RW), | |
.LCD_RSTN(LCD_RSTN), | |
.LCD_CS1(LCD_CS1), | |
.LCD_CS2(LCD_CS2), | |
.LCD_DI(LCD_DI), | |
.to_mode(to_mode), | |
.change_mode(change_mode), | |
.please_wait(please_wait), | |
//.mem_monitor1(mem_monitor1), | |
.mem_monitor2(mem_monitor2), | |
//.mem_monitor3(mem_monitor3), | |
.symbol_to_insert(symbol_to_insert), | |
.insert(insert), | |
.delete(delete), | |
.cursor_dir(cursor_dir), | |
.move_cursor(move_cursor), | |
.output_device(output_device) | |
); | |
/* | |
always@(posedge working_clock) begin | |
output_device <= output_device_next; | |
end | |
always@(*) begin | |
output_device_next = output_device; | |
if(insert && symbol_to_insert == ceo) | |
output_device_next = output_device+1; | |
else if(delete && mem_monitor1[7:0]==ceo) | |
output_device_next = output_device+1; | |
else if(move_cursor) | |
if(move_dir==1'b1 && mem_monitor2[7:0]==ceo) | |
output_device_next = output_device+1; | |
else if(move_dir==1'b0 && mem_monitor1[7:0]==ceo) | |
output_device_next = output_device+1; | |
end | |
*/ | |
endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Controller_module ( | |
input controller_change_mode //sync var | |
); | |
reg controller_mode=0; | |
parameter hat = 4'b0000, | |
add = 4'b0001, | |
sub = 4'b0010, | |
mol = 4'b0011, | |
mor = 4'b0100, | |
inp = 4'b0101, | |
oup = 4'b0110, | |
lol = 4'b0111, | |
lor = 4'b1000, | |
ceo = 4'b1001, | |
zer = 4'b1010, | |
pas = 4'b1011; | |
//declare: working_clock | |
//tape | |
Tape_module tape( | |
.working_clock(working_clock), | |
.tape_new_symbol(keypad_symbol), | |
.tape_set_symbol(tape_set_symbol), | |
.tape_move_dir(tape_move_dir), | |
.tape_move(tape_move), | |
.tape_symbol(tape_symbol), | |
.reset(tape_reset), | |
.roll_back(tape_roll_back), | |
.tape_delete(tape_delete) | |
); | |
wire tape_symbol; | |
//reg [3:0]tape_new_symbol; | |
reg tape_move_dir; | |
reg tape_set_symbol, tape_set_symbol_next; | |
reg tape_move, tape_move_next; | |
reg tape_roll_back, tape_roll_back_next; | |
reg tape_delete, tape_delete_next; | |
//memory | |
Memory_module memory( | |
.working_clock(working_clock), | |
.ptr_value(ptr_value), | |
.ptr_new_value(ptr_new_value), | |
.ptr_move_dir(ptr_move_dir), | |
.ptr_set_value(ptr_set_value), | |
.ptr_move(ptr_move), | |
.reset(mem_reset), | |
.roll_back(ptr_roll_back), | |
.mem_monitor2(mem_monitor2), | |
); | |
wire [7:0]ptr_value; | |
wire [13:0]mem_monitor2; | |
reg [7:0]ptr_new_value; | |
reg ptr_move_dir; | |
reg ptr_set_value, ptr_set_value_next; | |
reg ptr_move, ptr_move_next; | |
reg ptr_roll_back, ptr_roll_back_next; | |
//keypaddriver,facilities are not assign yet | |
KeypadDriver_module keypad_driver( | |
.reset(keypad_reset), | |
.working_clock(working_clock), | |
.to_mode(controller_mode), | |
.change_mode(keypad_change_mode), | |
.cmd_mode(cmd_mode), | |
.symbol(keypad_symbol), | |
.available(keypad_available), | |
.explicit_pull_key(keypad_pull_key) //as signal | |
); | |
wire cmd_mode; | |
wire keypad_symbol; | |
wire keypad_available; | |
//reg keypad_to_mode; | |
reg keypad_change_mode, keypad_change_mode_next; | |
//LED ,facilities are not assign yet | |
reg [7:0]led_char; | |
reg led_update, led_update_next; | |
//14seg ,facilities are not assign yet | |
reg [7:0]seg_char; | |
reg seg_update, seg_update_next; | |
//Console ,facilities are not assign yet | |
Console_module console( | |
.console_reset(console_reset), | |
.console_to_mode(controller_mode), | |
.console_change_mode(console_change_mode), | |
.console_please_wait(console_please_wait), | |
.console_mem_monitor2(mem_monitor2), | |
.console_symbol_to_insert(keypad_symbol), | |
.console_insert(console_insert), | |
.console_delete(console_delete), | |
.console_cursor_dir(console_cursor_dir | keypad_cursor_move_dir), | |
.console_move_cursor(console_move_cursor) | |
); | |
//reg console_to_mode; | |
reg console_cursor_dir; | |
reg console_change_mode, console_change_mode_next; | |
reg console_please_wait, console_please_wait_next; | |
reg console_insert, console_insert_next; | |
reg console_delete, console_delete_next; | |
reg console_move_cursor, console_move_cursor_next; | |
//wire console_reset | |
//wire tape_reset, aux_tape_reset,aux_tape_reset_next; | |
//wire mem_reset, aux_mem_reset,aux_mem_reset_next; | |
//wire keypad_pull_key, aux_keypad_pull_key,aux_keypad_pull_key_next; | |
//wire keypad_reset, aux_keypad_reset,aux_keypad_reset_next; | |
//wire led_reset, aux_led_reset,aux_led_reset_next; | |
//wire seg_reset, aux_seg_reset,aux_seg_reset_next; | |
/*SMDL | |
(state-machine | |
(clock "working_clock") | |
(init-state init) | |
(state | |
(default | |
(sync-var | |
("tape_set_symbol" "1'b0") | |
("tape_move" "1'b0") | |
("tape_roll_back" "1'b0") | |
("tape_delete" "1'b0") | |
("ptr_set_value" "1'b0") | |
("ptr_move" "1'b0") | |
("ptr_roll_back" "1'b0") | |
("keypad_change_mode" "1'b0") | |
("led_update" "1'b0") | |
("seg_update" "1'b0") | |
("console_change_mode" "1'b0") | |
("console_please_wait" "1'b0") | |
("console_insert" "1'b0") | |
("console_delete" "1'b0") | |
("console_move_cursor" "1'b0") | |
) | |
(reg | |
("tape_move_dir" "1'b0") | |
("tape_new_symbol" "3'b000") | |
("ptr_move_dir" "1'b0") | |
("ptr_new_value" "8'd0") | |
("console_cursor_dir" "1'b0") | |
("controller_mode" "1'b0") | |
)) | |
(init | |
(sync-var | |
("keypad_change_mode" "1'b1") | |
("console_change_mode" "1'b1")) | |
(reg | |
("keypad_to_mode" "1'b0") | |
("console_to_mode" "1'b0"))) | |
(edit) | |
(edit_insert_symbol | |
(sync-var | |
("console_insert" "1'b1") | |
("tape_set_symbol" "1'b1"))) | |
(edit_delete_symbol | |
(sync-var | |
("console_delete" "1'b1") | |
("tape_delete" "1'b1"))) | |
(trans-func | |
((init) | |
(edit "tape_reset" | |
"mem_reset" | |
"led_reset" | |
"seg_reset")) | |
;edit transfunc | |
((edit (and | |
("keypad_available" "==" "1'b1") | |
("cmd_mode" "==" "1'd0"))) | |
(edit_insert_symbol)) | |
((edit (and | |
("keypad_available" "==" "1'b1") | |
("cmd_mode" "==" "1'd1"))) | |
(edit_delete_symbol)) | |
((edit ("controller_change_mode" "==" "1'b1")) | |
(edit_to_exe)) | |
((edit) (edit)) | |
((edit_insert_symbol) | |
(edit_move_tapeR "keypad_pull_key")) | |
((edit_delete_symbol) | |
(edit_move_tapeL "keypad_pull_key")) | |
((edit_move_tapeR) (edit)) | |
((edit_move_tapeL) (edit)) | |
;gray area | |
((edit_to_exe) (exe)) | |
((exe_to_edit) (edit)) | |
;exe trans funcs | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module KeypadDriver_module( | |
input reset, | |
input keypad_clock, | |
input working_clock, | |
input to_mode, //0 for edit, 1 for exe | |
input change_mode, | |
//edit mode | |
output reg cmd_mode, //0 for symbol 1 for delete | |
output reg [3:0]symbol,//cmd_mode=0 | |
//output reg cursor_move_dir, //cmd_mode=1 | |
//output reg backspace, //cmd_mode=2 | |
//execute mode | |
//use "symbol" port | |
output reg available = 1'b0, | |
input explicit_pull_key | |
); | |
reg mode,mode_next = 0; //0 for edit, 1 for exe | |
reg cmd_mode_next = 0; | |
reg [3:0]symbol_next; | |
wire pull_key; | |
wire auto_pull_key; | |
reg aux_auto_pull_key,aux_auto_pull_key_next; | |
assign auto_pull_key = aux_auto_pull_key_next & working_clock; | |
assign pull_key = explicit_pull_key | auto_pull_key; | |
keypad kp( .key_available(key_available), | |
.key(key), | |
.pull_key(pull_key)); | |
wire key_available; | |
reg available_next = 1'b0; | |
wire [3:0]key; | |
parameter INIT = 2'b00, | |
EDIT = 2'b01, | |
EXE = 2'b10; | |
parameter hat = 4'b0000, | |
add = 4'b0001, | |
sub = 4'b0010, | |
mol = 4'b0011, | |
mor = 4'b0100, | |
inp = 4'b0101, | |
oup = 4'b0110, | |
lol = 4'b0111, | |
lor = 4'b1000, | |
ceo = 4'b1001, | |
zer = 4'b1010, | |
pas = 4'b1011; | |
always@(posedge working_clock,posedge reset) begin | |
if(reset) begin | |
_state <= INIT; | |
available <= 1'b0; | |
end else begin | |
_state <= _state_next; | |
mode <= mode_next; | |
available <= available_next; | |
cmd_mode <= cmd_mode_next; | |
symbol <= symbol_next; | |
cursor_move_dir <= cursor_move_dir_next; | |
backspace <= backspace_next; | |
clear_memory <= clear_memory_next; | |
end | |
end | |
always@(*) begin | |
mode_next = mode; | |
_state_next = INIT; | |
cmd_mode_next = 0; | |
symbol_next = symbol; | |
available_next = 1'b0; | |
aux_auto_pull_key_next = 1'b0; | |
case(_state) | |
INIT: begin | |
if(change_mode) begin | |
if(to_mode==1'b1) | |
_state_next = EXE; | |
else | |
_state_next = EDIT; | |
end else | |
_state_next = INIT; | |
end | |
EDIT: begin | |
if(key_available) begin | |
available_next = 1'b1; | |
case (key) | |
4'h0: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = zer; | |
end | |
4'h1: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = inp; | |
end | |
4'h2: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = oup; | |
end | |
4'h3: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = pas; | |
end | |
4'h4: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = mol; | |
end | |
4'h5: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = sub; | |
end | |
4'h6: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = lol; | |
end | |
4'h7: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = mor; | |
end | |
4'h8: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = add; | |
end | |
4'h9: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = lor; | |
end | |
4'ha: begin | |
cmd_mode_next = 1'd0; | |
symbol_next = ceo; | |
end | |
4'hb: begin | |
cmd_mode_next = 1'd0; | |
end | |
default: begin | |
available_next = 1'b0; | |
aux_auto_pull_key_next = 1'b1; | |
end | |
endcase | |
end | |
if(change_mode && to_mode==1'b1) begin | |
_state_next = EXE; | |
end else begin | |
_state_next = EDIT; | |
end | |
end | |
EXE: begin | |
if(key_available) begin | |
available_next = 1'b1; | |
symbol_next = key; | |
end | |
if(change_mode && to_mode==1'b0) begin | |
_state_next = EDIT; | |
end else begin | |
_state_next = EXE; | |
end | |
end | |
default: begin | |
_state_next = INIT; | |
end | |
endcase | |
end | |
endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Memory_module ( | |
input working_clock, | |
output [7:0]ptr_value, | |
input [7:0]ptr_new_value, | |
input ptr_move_dir, | |
input ptr_set_value, //signal | |
input ptr_move, //signal | |
input reset, | |
input roll_back, | |
//output [13:0]mem_monitor1,//{mem_addr,mem_content} | |
output [13:0]mem_monitor2, | |
//output [13:0]mem_monitor3 | |
output reg available = 1'b0 | |
); | |
reg available_next = 1'b0; | |
reg [0:511]memory,memory_next; //8bit * 128 | |
//reg [8:0]ptr = 9'd0; | |
//reg [8:0]ptr_next; | |
assign ptr_value = memory[0:7]; | |
reg [5:0]address = 6'd0; | |
reg [5:0]address_next; | |
reg [5:0]mov_counter,mov_counter_next; | |
//assign mem_monitor1 = {address-6'd1,memory[508:511]}; | |
assign mem_monitor2 = {address,ptr_value}; | |
//assign mem_monitor3 = {address+6'd1,memory[8:15]}; | |
parameter INIT = 2'd0, | |
WAIT = 2'd1, | |
MOVL = 2'd2, | |
MOVR = 2'd3; | |
reg [1:0]_state = INIT; | |
reg [1:0]_state_next = INIT; | |
always@(posedge working_clock,posedge reset) begin | |
if(reset) begin | |
_state <= INIT; | |
available <= 1'b0; | |
address <= 6'd0; | |
mov_counter <= 6'd0; | |
end else begin | |
_state <= _state_next; | |
memory <= memory_next; | |
//ptr <= ptr_next; | |
address <= address_next; | |
available <= available_next; | |
mov_counter <= mov_counter_next; | |
end | |
end | |
always@(*) begin | |
//ptr_next = ptr; | |
memory_next = memory; | |
address_next = address; | |
available_next = 1'b0; | |
mov_counter_next = mov_counter; | |
case(_state) | |
INIT: begin | |
memory_next = 512'd0; | |
_state_next = WAIT; | |
//ptr_next = 9'd0; | |
address_next = 6'd0; | |
available_next = 1'b1; | |
mov_counter_next = 6'b0; | |
end | |
WAIT: begin | |
if(ptr_set_value) begin | |
memory_next = {ptr_new_value,memory[8:511]}; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
end else if(ptr_move && | |
ptr_move_dir==1'b1 && | |
address < 6'd63) begin | |
mov_counter_next = 6'd1; | |
_state_next = MOVR; | |
end else if(ptr_move && | |
ptr_move_dir==1'b0 && | |
address > 6'd0) begin | |
mov_counter_next = 6'd1; | |
_state_next = MOVL; | |
end else if(roll_back && address>6'd0) begin | |
_state_next = MOVL; | |
mov_counter_next = address; | |
end else begin | |
_state_next = WAIT; | |
available_next = 1'b1; | |
end | |
end | |
MOVL: begin | |
memory_next = {memory[504:511],memory[0:503]}; | |
if(mov_counter == 6'd1) begin | |
mov_counter_next = 6'd0; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
address_next = address - 1; | |
end else begin | |
mov_counter_next = mov_counter - 1; | |
address_next = address - 1; | |
_state_next = MOVL; | |
end | |
end | |
MOVR: begin | |
memory_next = {memory[8:511],memory[0:7]}; | |
if(mov_counter == 6'd1) begin | |
mov_counter_next = 6'd0; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
address_next = address + 1; | |
end else begin | |
mov_counter_next = mov_counter - 1; | |
address_next = address + 1; | |
_state_next = MOVR; | |
end | |
end | |
default: | |
_state_next = INIT; | |
endcase | |
end | |
endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Tape_module ( | |
input working_clock, | |
input [3:0]tape_new_symbol, | |
input tape_set_symbol, | |
input tape_move_dir, | |
input tape_move, | |
output [3:0]tape_symbol, | |
input reset, | |
input roll_back, | |
input tape_delete, | |
output reg available = 1'b0 | |
); | |
reg available_next = 1'b0; | |
reg [0:511]tape,tape_next = 512'd0; //128*4bit symbols | |
//reg [8:0]tape_ptr=0; | |
//reg [8:0]tape_ptr_next; | |
assign tape_symbol = tape[0:3]; | |
reg [6:0]counter,counter_next = 7'd0; | |
reg [6:0]mov_counter,mov_counter_next; | |
parameter hat = 4'b0000, | |
add = 4'b0001, | |
sub = 4'b0010, | |
mol = 4'b0011, | |
mor = 4'b0100, | |
inp = 4'b0101, | |
oup = 4'b0110, | |
lol = 4'b0111, | |
lor = 4'b1000, | |
ceo = 4'b1001, | |
zer = 4'b1010, | |
pas = 4'b1011; | |
parameter INIT = 2'd0, | |
WAIT = 2'd1, | |
MOVL = 2'd2, | |
MOVR = 2'd3; | |
reg [1:0]_state = INIT; | |
reg [1:0]_state_next = INIT; | |
always@(posedge working_clock,posedge reset) begin | |
if(reset) begin | |
_state <= INIT; | |
available <= 1'b0; | |
counter <= 7'd0; | |
mov_counter <= 7'd0; | |
end else begin | |
_state <= _state_next; | |
tape <= tape_next; | |
//tape_ptr <= tape_ptr_next; | |
available <= available_next; | |
counter <= counter_next; | |
mov_counter <= mov_counter_next; | |
end | |
end | |
always@(*) begin | |
//tape_ptr_next = tape_ptr; | |
tape_next = tape; | |
available_next = 1'b0; | |
mov_counter_next = mov_counter; | |
case(_state) | |
INIT: begin | |
tape_next = 512'd0; | |
//tape_ptr_next = 9'd0; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
counter_next = 7'd0; | |
mov_counter_next = 7'd0; | |
end | |
WAIT: begin | |
if(tape_set_symbol) begin | |
tape_next = {tape_new_symbol,tape[4:511]}; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
end else if(tape_move && | |
tape_move_dir==1'b1 && | |
counter<7'd127) begin | |
mov_counter_next = 7'd1; | |
_state_next = MOVR; | |
end else if(tape_move && | |
tape_move_dir==1'b0 && | |
counter>7'd0) begin | |
mov_counter_next = 7'd1; | |
_state_next = MOVL; | |
end else if(roll_back && counter>7'd0) begin | |
_state_next = MOVL; | |
mov_counter_next = counter; | |
end else if(tape_delete) begin | |
tape_next = {hat,tape[4:511]}; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
end else begin | |
_state_next = WAIT; | |
available_next = 1'b1; | |
end | |
end | |
MOVL: begin | |
tape_next = {tape[508:511],tape[0:507]}; | |
if(mov_counter == 7'd1) begin | |
mov_counter_next = 7'd0; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
counter_next = counter - 1; | |
end else begin | |
mov_counter_next = mov_counter - 1; | |
counter_next = counter - 1; | |
_state_next = MOVL; | |
end | |
end | |
MOVR: begin | |
tape_next = {tape[4:511],tape[0:3]}; | |
if(mov_counter == 7'd1) begin | |
mov_counter_next = 7'd0; | |
_state_next = WAIT; | |
available_next = 1'b1; | |
counter_next = counter + 1; | |
end else begin | |
mov_counter_next = mov_counter - 1; | |
counter_next = counter + 1; | |
_state_next = MOVR; | |
end | |
end | |
default: | |
_state_next = INIT; | |
endcase | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment