Created
December 2, 2018 07:36
-
-
Save cibomahto/c18c04f9f182d4549eba780d6829a972 to your computer and use it in GitHub Desktop.
This file contains 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
/****************************************************************************** | |
* * | |
* Copyright 2016 myStorm Copyright and related * | |
* rights are licensed under the Solderpad Hardware License, Version 0.51 * | |
* (the “License”); you may not use this file except in compliance with * | |
* the License. You may obtain a copy of the License at * | |
* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable * | |
* law or agreed to in writing, software, hardware and materials * | |
* distributed under this License is distributed on an “AS IS” BASIS, * | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * | |
* implied. See the License for the specific language governing * | |
* permissions and limitations under the License. * | |
* * | |
******************************************************************************/ | |
module blink( | |
input clk, | |
input rst, | |
output led_r, | |
output led_g, | |
output led_b | |
); | |
//reg [1:0] state; | |
reg [28:0] count; | |
wire direction; // Fade in/out direction | |
wire [1:0] state; // Current phase (fade r,g,b, or w) | |
reg [2:0] leds; // LED output states | |
reg pwm_state; | |
wire [7:0] correction; | |
assign led_r = !leds[0]; | |
assign led_g = !leds[1]; | |
assign led_b = !leds[2]; | |
assign state = count[28:27]; | |
assign direction = count[26]; | |
correction_lut_8 corrector ( | |
.value(count[25:18]), | |
.corrected(correction) | |
); | |
always @(posedge clk) | |
if(rst) begin | |
count <= 0; | |
end | |
else begin | |
pwm_state <= 0; | |
leds <= 0; | |
count <= count + 1; | |
if(direction == 0) begin | |
if(correction > count[7:0]) | |
pwm_state <= 1; | |
end | |
else begin | |
if(correction < count[7:0]) | |
pwm_state <= 1; | |
end | |
case(state) | |
0: | |
leds[0] <= pwm_state; | |
1: | |
leds[1] <= pwm_state; | |
2: | |
leds[2] <= pwm_state; | |
3: | |
begin | |
leds[0] <= pwm_state; | |
leds[1] <= pwm_state; | |
leds[2] <= pwm_state; | |
end | |
endcase | |
end | |
endmodule |
This file contains 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 chip ( | |
output LED_R, | |
output LED_G, | |
output LED_B, | |
output SPI_C_0, | |
output SPI_D_0, | |
output SPI_C_1, | |
output SPI_D_1, | |
output SPI_C_2, | |
output SPI_D_2, | |
output SPI_C_3, | |
output SPI_D_3, | |
output START_FLAG | |
); | |
wire clk; | |
wire led_r; | |
wire led_g; | |
wire led_b; | |
wire start_flag; | |
reg [1:0] halfclock; | |
always @(posedge clk) | |
halfclock <= halfclock + 1; | |
SB_HFOSC u_hfosc ( | |
.CLKHFPU(1'b1), | |
.CLKHFEN(1'b1), | |
.CLKHF(clk) | |
); | |
blink my_blink ( | |
.clk(clk), | |
.rst(0), | |
.led_r(led_r), | |
.led_g(led_g), | |
.led_b(led_b) | |
); | |
assign LED_R = led_r; | |
assign LED_G = led_g; | |
assign LED_B = led_b; | |
icnd2110 my_icnd_0( | |
.clk(halfclock[0]), | |
.rst(0), | |
.chipcount(200), | |
.cfg_pwm_wider(0), | |
.cfg_up(1), | |
.spi_c(SPI_C_0), | |
.spi_d(SPI_D_0), | |
.start_flag(START_FLAG) | |
); | |
icnd2110 my_icnd_1( | |
.clk(halfclock[0]), | |
.rst(0), | |
.chipcount(200), | |
.cfg_pwm_wider(0), | |
.cfg_up(1), | |
.spi_c(SPI_C_1), | |
.spi_d(SPI_D_1), | |
.start_flag() | |
); | |
icnd2110 my_icnd_2( | |
.clk(halfclock[0]), | |
.rst(0), | |
.chipcount(200), | |
.cfg_pwm_wider(0), | |
.cfg_up(1), | |
.spi_c(SPI_C_2), | |
.spi_d(SPI_D_2), | |
.start_flag() | |
); | |
icnd2110 my_icnd_3( | |
.clk(halfclock[0]), | |
.rst(0), | |
.chipcount(200), | |
.cfg_pwm_wider(0), | |
.cfg_up(1), | |
.spi_c(SPI_C_3), | |
.spi_d(SPI_D_3), | |
.start_flag() | |
); | |
endmodule |
This file contains 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 icnd2110( | |
input clk, | |
input rst, | |
input [7:0] chipcount, | |
input cfg_pwm_wider, // Enhancement for low gray (1=enable) | |
input cfg_up, // Ghosting reduction (1=enable) | |
output spi_c, | |
output spi_d, | |
output start_flag | |
); | |
reg [3:0] state; // Current state machine mode | |
reg [10:0] counter; // 8-bit step counter | |
reg [7:0] chips; // Number of ICND2110 chips present | |
reg [9:0] val; // PWM value (top 8 bits are significant) | |
reg [5:0] outp; // current output | |
reg [7:0] pwm_val; | |
wire [15:0] correction; | |
reg data; | |
reg start_flag_r; | |
assign spi_c = !clk; // Off by 1/2 phase? | |
assign spi_d = data; | |
assign start_flag = start_flag_r; | |
// The LUT takes the majority of our space, can we move it to a ram? | |
correction_lut_16 corrector ( | |
.value(pwm_val), | |
.corrected(correction) | |
); | |
/* | |
assign correction[15:8] = val; | |
assign correction[7:0] = 0; | |
*/ | |
always @(posedge clk) | |
if(rst) begin | |
state <= 0; | |
data <= 0; | |
val <= 0; | |
outp <= 0; | |
end | |
else begin | |
start_flag_r <= 0; | |
data <= 0; | |
if(val[9] == 0) | |
pwm_val <= val[8:1]; | |
else | |
pwm_val <= (255 - val[8:1]); | |
case(state) | |
// Many states here: | |
// 0. wait for start | |
0: | |
// TODO: implement start signal | |
begin | |
start_flag_r <= 1; | |
state <= 1; | |
counter <= 0; | |
chips <= chipcount; | |
val <= val + 1; // output value counter | |
if(val == 0) | |
outp <= outp+1; | |
if(outp > 11) | |
outp <= 0; | |
end | |
// 1. start (128 bits of 1) | |
1: | |
begin | |
data <= 1; | |
counter <= counter +1; | |
if(counter == 127) begin | |
state <= state + 1; | |
counter <= 0; | |
end | |
end | |
// 2. blank (16 bits of 0) | |
2,4,6,8: | |
begin | |
counter <= counter +1; | |
if(counter == 15) begin | |
state <= state + 1; | |
counter <= 0; | |
end | |
end | |
// 3. reg (16 bit register value) | |
3: | |
begin | |
counter <= counter + 1; | |
case(counter[3:0]) | |
11: | |
data <= cfg_pwm_wider; | |
12: | |
data <= cfg_up; | |
13,14,15: | |
data <= 1; | |
default: | |
data <= 0; | |
endcase | |
if(counter == 15) begin | |
state <= state + 1; | |
counter <= 0; | |
end | |
end | |
// 4. blank (16 bits of 0) | |
// for n chips: | |
// 5. chip x, out5-out0 (16 x 6 bits) | |
5, 7: | |
begin | |
counter <= counter + 1; | |
if(((state == 5) && (counter[6:4] == outp)) | |
|| ((state == 7) && (counter[6:4] == (outp - 6)))) begin | |
case(counter[3:0]) | |
0: data <= correction[15]; | |
1: data <= correction[14]; | |
2: data <= correction[13]; | |
3: data <= correction[12]; | |
4: data <= correction[11]; | |
5: data <= correction[10]; | |
6: data <= correction[9]; | |
7: data <= correction[8]; | |
8: data <= correction[7]; | |
9: data <= correction[6]; | |
10: data <= correction[5]; | |
11: data <= correction[4]; | |
12: data <= correction[3]; | |
13: data <= correction[2]; | |
14: data <= correction[1]; | |
15: data <= correction[0]; | |
endcase | |
end | |
if(counter == (16*6-1)) begin | |
counter <= 0; | |
if(state == 5) begin | |
state <= state + 1; | |
end | |
else begin | |
chips <= chips - 1; | |
if(chips > 0) | |
state <= 4; | |
else | |
state <= state + 1; | |
end | |
end | |
end | |
// 6. blank | |
// 7. chip x, out11-out6 (16 x 6 bits) | |
// 8. blank | |
// 9. frame end (145 bits of 1) | |
9: | |
begin | |
data <= 1; | |
counter <= counter +1; | |
if(counter == 144) begin | |
// state <= state + 1; | |
state <= 0; | |
counter <= 0; | |
end | |
end | |
default: | |
state <= 0; | |
endcase | |
end | |
endmodule |
This file contains 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 lut(count_out, angle); | |
input [2:0] count_out; | |
output [11:0] angle; | |
reg [11:0] angle; | |
always @(count_out) | |
case (count_out) | |
3'b000: angle=12'b001000000000; //0 45 45 | |
3'b001: angle=12'b000100101110; //1 26.54 26.57 | |
3'b010: angle=12'b000010100000; //2 14.06 14.036 | |
3'b011: angle=12'b000001010001; //3 7.12 7.13 | |
3'b100: angle=12'b000000101001; //4 3.604 3.576 | |
3'b101: angle=12'b000000010100; //5 1.76 1.79 | |
3'b110: angle=12'b000000001010; //6 0.88 0.9 | |
3'b111: angle=12'b000000000101; //7 0.44 0.45 | |
default: angle=12'b001000000000; //default 0 | |
endcase | |
endmodule | |
''' | |
header = ''' | |
module correction_lut_16(value, corrected); | |
input [7:0] value; | |
output [15:0] corrected; | |
reg [15:0] corrected; | |
always @(value) | |
case (value) | |
''' | |
footer = ''' | |
endcase | |
endmodule | |
''' | |
out = open('correction_lut_16.v','w') | |
out.write(header) | |
for val in range(0,256): | |
out.write("%i: corrected=%i;\n" % (val,int(65535*pow(val/255.0,1.8)))) | |
out.write(footer) |
This file contains 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 lut(count_out, angle); | |
input [2:0] count_out; | |
output [11:0] angle; | |
reg [11:0] angle; | |
always @(count_out) | |
case (count_out) | |
3'b000: angle=12'b001000000000; //0 45 45 | |
3'b001: angle=12'b000100101110; //1 26.54 26.57 | |
3'b010: angle=12'b000010100000; //2 14.06 14.036 | |
3'b011: angle=12'b000001010001; //3 7.12 7.13 | |
3'b100: angle=12'b000000101001; //4 3.604 3.576 | |
3'b101: angle=12'b000000010100; //5 1.76 1.79 | |
3'b110: angle=12'b000000001010; //6 0.88 0.9 | |
3'b111: angle=12'b000000000101; //7 0.44 0.45 | |
default: angle=12'b001000000000; //default 0 | |
endcase | |
endmodule | |
''' | |
header = ''' | |
module correction_lut_8(value, corrected); | |
input [7:0] value; | |
output [7:0] corrected; | |
reg [7:0] corrected; | |
always @(value) | |
case (value) | |
''' | |
footer = ''' | |
endcase | |
endmodule | |
''' | |
out = open('correction_lut_8.v','w') | |
out.write(header) | |
for val in range(0,256): | |
out.write("%i: corrected=%i;\n" % (val,int(255*pow(val/255.0,1.8)))) | |
out.write(footer) |
This file contains 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
chip.bin: chip.v blink.v upduino_v2.pcf | |
yosys -q -p "synth_ice40 -blif chip.blif" chip.v blink.v correction_lut_8.v correction_lut_16.v icnd2110.v | |
arachne-pnr -d 5k -P sg48 -p upduino_v2.pcf chip.blif -o chip.txt | |
icepack chip.txt chip.bin | |
.PHONY: flash | |
flash: | |
iceprog chip.bin | |
.PHONY: clean | |
clean: | |
$(RM) -f chip.blif chip.txt chip.ex chip.bin |
This file contains 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
set_io LED_R 41 | |
set_io LED_G 39 | |
set_io LED_B 40 | |
set_io START_FLAG 28 | |
set_io SPI_C_0 2 | |
set_io SPI_D_0 46 | |
set_io SPI_C_1 47 | |
set_io SPI_D_1 45 | |
set_io SPI_C_2 48 | |
set_io SPI_D_2 3 | |
set_io SPI_C_3 4 | |
set_io SPI_D_3 44 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment