aboutsummaryrefslogtreecommitdiffstats
path: root/misc/yosysjs/demo02.html
blob: 9191db98d42963f8ca830f3a121e523f847261e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<html><head>
	<title>YosysJS Example Application #02</title>
	<script type="text/javascript" src="yosysjs.js"></script>
</head><body>
	<div id="popup" style="position: fixed; left: 0; top: 0; width:100%; height:100%; text-align:center; z-index: 1000;"><div
		style="width:300px; margin: 200px auto; background-color: #88f; border:3px dashed #000;
		padding:15px; text-align:center;"><span id="popupmsg">Loading...</span></div>
	</div>
	<h1>YosysJS Example Application #02</h1>
	<textarea id="code" style="width: 800px; height: 300px;">
// borrowed with some modifications from
// http://www.ee.ed.ac.uk/~gerard/Teach/Verilog/manual/Example/lrgeEx2/cooley.html
module up3down5(clock, data_in, up, down, carry_out, borrow_out, count_out, parity_out);

input [8:0] data_in;
input clock, up, down;

output reg [8:0] count_out;
output reg carry_out, borrow_out, parity_out;

reg [9:0] cnt_up, cnt_dn;
reg [8:0] count_nxt;

always @(posedge clock)
begin
	cnt_dn = count_out - 3'b 101;
	cnt_up = count_out + 2'b 11;

	case ({up,down})
		2'b 00 : count_nxt = data_in;
		2'b 01 : count_nxt = cnt_dn;
		2'b 10 : count_nxt = cnt_up;
		2'b 11 : count_nxt = count_out;
		default : count_nxt = 9'bX;
	endcase

	parity_out  &lt;= ^count_nxt;
	carry_out   &lt;= up &amp; cnt_up[9];
	borrow_out  &lt;= down &amp; cnt_dn[9];
	count_out   &lt;= count_nxt;
end

endmodule
	</textarea><p/>
	<input type="button" value="Before Behavioral Synth" onclick="synth1()">
	<input type="button" value="After Behavioral Synth" onclick="synth2()">
	<input type="button" value="After RTL Synth" onclick="synth3()">
	<input type="button" value="After Gate-Level Synth" onclick="synth4()"><p/>
	<svg id="svg" width="800"></svg>
	</td></tr></table>
	<script type="text/javascript">
		YosysJS.load_viz();
		function on_ys_ready() {
			document.getElementById('popup').style.visibility = 'hidden';
			document.getElementById('popupmsg').textContent = 'Please wait..';
		}
		function handle_run_errors(logmsg, errmsg) {
			if (errmsg != "") {
				window.alert(errmsg);
				document.getElementById('popup').style.visibility = 'hidden';
			}
		}
		function synth1() {
			document.getElementById('popup').style.visibility = 'visible';
			ys.write_file("input.v", document.getElementById('code').value);
			ys.run('design -reset; read_verilog input.v; show -stretch', handle_run_errors);
			ys.read_file('show.dot', (function(text){
				console.log(ys.errmsg);
				if (ys.errmsg == "") YosysJS.dot_into_svg(text, 'svg');
				document.getElementById('popup').style.visibility = 'hidden';
			}));
		}
		function synth2() {
			document.getElementById('popup').style.visibility = 'visible';
			ys.write_file("input.v", document.getElementById('code').value);
			ys.run('design -reset; read_verilog input.v; proc; opt_clean; show -stretch', handle_run_errors);
			ys.read_file('show.dot', (function(text){
				if (ys.errmsg == "") YosysJS.dot_into_svg(text, 'svg');
				document.getElementById('popup').style.visibility = 'hidden';
			}));
		}
		function synth3() {
			document.getElementById('popup').style.visibility = 'visible';
			ys.write_file("input.v", document.getElementById('code').value);
			ys.run('design -reset; read_verilog input.v; synth -run coarse; show -stretch', handle_run_errors);
			ys.read_file('show.dot', (function(text){
				if (ys.errmsg == "") YosysJS.dot_into_svg(text, 'svg');
				document.getElementById('popup').style.visibility = 'hidden';
			}));
		}
		function synth4() {
			document.getElementById('popup').style.visibility = 'visible';
			ys.write_file("input.v", document.getElementById('code').value);
			ys.run('design -reset; read_verilog input.v; synth -run coarse; synth -run fine; show -stretch', handle_run_errors);
			ys.read_file('show.dot', (function(text){
				if (ys.errmsg == "") YosysJS.dot_into_svg(text, 'svg');
				document.getElementById('popup').style.visibility = 'hidden';
			}));
		}
		var ys = YosysJS.create_worker(on_ys_ready);
		ys.verbose(true);
	</script>
</body></html>
ss="mh">0x5a); return hdr; #else return (struct xmalloc_hdr *)p - 1; #endif } static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block) { struct xmalloc_hdr *extra; size_t leftover = block - size; /* If enough is left to make a block, put it on free list. */ if ( leftover >= (2 * sizeof(struct xmalloc_hdr)) ) { extra = (struct xmalloc_hdr *)((unsigned long)hdr + size); extra->size = leftover; add_to_freelist(extra); } else { size = block; } hdr->size = size; /* Debugging aid. */ hdr->freelist.next = hdr->freelist.prev = NULL; } static void *xmalloc_new_page(size_t size) { struct xmalloc_hdr *hdr; unsigned long flags; hdr = alloc_xenheap_page(); if ( hdr == NULL ) return NULL; spin_lock_irqsave(&freelist_lock, flags); maybe_split(hdr, size, PAGE_SIZE); spin_unlock_irqrestore(&freelist_lock, flags); return data_from_header(hdr); } /* Big object? Just use the page allocator. */ static void *xmalloc_whole_pages(size_t size) { struct xmalloc_hdr *hdr; unsigned int pageorder = get_order_from_bytes(size); hdr = alloc_xenheap_pages(pageorder); if ( hdr == NULL ) return NULL; hdr->size = (1 << (pageorder + PAGE_SHIFT)); /* Debugging aid. */ hdr->freelist.next = hdr->freelist.prev = NULL; return data_from_header(hdr); } /* Return size, increased to alignment with align. */ static inline size_t align_up(size_t size, size_t align) { return (size + align - 1) & ~(align - 1); } void *_xmalloc(size_t size, size_t align) { struct xmalloc_hdr *i; unsigned long flags; /* We currently always return cacheline aligned. */ BUG_ON(align > SMP_CACHE_BYTES); #if XMALLOC_DEBUG /* Add room for canaries at start and end of data block. */ size += 2 * SMP_CACHE_BYTES; #endif /* Add room for header, pad to align next header. */ size += sizeof(struct xmalloc_hdr); size = align_up(size, __alignof__(struct xmalloc_hdr)); /* For big allocs, give them whole pages. */ if ( size >= PAGE_SIZE ) return xmalloc_whole_pages(size); /* Search free list. */ spin_lock_irqsave(&freelist_lock, flags); list_for_each_entry( i, &freelist, freelist ) { if ( i->size < size ) continue; del_from_freelist(i); maybe_split(i, size, i->size); spin_unlock_irqrestore(&freelist_lock, flags); return data_from_header(i); } spin_unlock_irqrestore(&freelist_lock, flags); /* Alloc a new page and return from that. */ return xmalloc_new_page(size); } void xfree(void *p) { unsigned long flags; struct xmalloc_hdr *i, *tmp, *hdr; if ( p == NULL ) return; hdr = header_from_data(p); /* We know hdr will be on same page. */ BUG_ON(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK)); /* Not previously freed. */ BUG_ON(hdr->freelist.next || hdr->freelist.prev); /* Big allocs free directly. */ if ( hdr->size >= PAGE_SIZE ) { free_xenheap_pages(hdr, get_order_from_bytes(hdr->size)); return; } /* Merge with other free block, or put in list. */ spin_lock_irqsave(&freelist_lock, flags); list_for_each_entry_safe( i, tmp, &freelist, freelist ) { unsigned long _i = (unsigned long)i; unsigned long _hdr = (unsigned long)hdr; /* Do not merge across page boundaries. */ if ( ((_i ^ _hdr) & PAGE_MASK) != 0 ) continue; /* We follow this block? Swallow it. */ if ( (_i + i->size) == _hdr ) { del_from_freelist(i); i->size += hdr->size; hdr = i; } /* We precede this block? Swallow it. */ if ( (_hdr + hdr->size) == _i ) { del_from_freelist(i); hdr->size += i->size; } } /* Did we merge an entire page? */ if ( hdr->size == PAGE_SIZE ) { BUG_ON((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0); free_xenheap_pages(hdr, 0); } else { add_to_freelist(hdr); } spin_unlock_irqrestore(&freelist_lock, flags); } /* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */